10855 lines
385 KiB
Plaintext
10855 lines
385 KiB
Plaintext
|
=head1 Introduction
|
||
|
|
||
|
C<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 C<GMP> or C<imath>.
|
||
|
The C<isl> library offers functionality that is similar
|
||
|
to that offered by the C<Omega> and C<Omega+> 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<CLooG> and as part of an equivalence checker of
|
||
|
static affine programs.
|
||
|
For bug reports, feature requests and questions,
|
||
|
visit the discussion group at
|
||
|
L<http://groups.google.com/group/isl-development>.
|
||
|
|
||
|
=head2 Backward Incompatible Changes
|
||
|
|
||
|
=head3 Changes since isl-0.02
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item * The old printing functions have been deprecated
|
||
|
and replaced by C<isl_printer> functions, see L<Input and Output>.
|
||
|
|
||
|
=item * Most functions related to dependence analysis have acquired
|
||
|
an extra C<must> argument. To obtain the old behavior, this argument
|
||
|
should be given the value 1. See L<Dependence Analysis>.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head3 Changes since isl-0.03
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item * The function C<isl_pw_qpolynomial_fold_add> has been
|
||
|
renamed to C<isl_pw_qpolynomial_fold_fold>.
|
||
|
Similarly, C<isl_union_pw_qpolynomial_fold_add> has been
|
||
|
renamed to C<isl_union_pw_qpolynomial_fold_fold>.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head3 Changes since isl-0.04
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item * All header files have been renamed from C<isl_header.h>
|
||
|
to C<isl/header.h>.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head3 Changes since isl-0.05
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item * The functions C<isl_printer_print_basic_set> and
|
||
|
C<isl_printer_print_basic_map> no longer print a newline.
|
||
|
|
||
|
=item * The functions C<isl_flow_get_no_source>
|
||
|
and C<isl_union_map_compute_flow> now return
|
||
|
the accesses for which no source could be found instead of
|
||
|
the iterations where those accesses occur.
|
||
|
|
||
|
=item * The functions C<isl_basic_map_identity> and
|
||
|
C<isl_map_identity> now take a B<map> space as input. An old call
|
||
|
C<isl_map_identity(space)> can be rewritten to
|
||
|
C<isl_map_identity(isl_space_map_from_set(space))>.
|
||
|
|
||
|
=item * The function C<isl_map_power> 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<isl_printer_print_qpolynomial>'s
|
||
|
C<ISL_FORMAT_ISL> output has changed.
|
||
|
Use C<ISL_FORMAT_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<isl_pw_aff_max> has been renamed to
|
||
|
C<isl_pw_aff_union_max>.
|
||
|
Similarly, the function C<isl_pw_aff_add> has been renamed to
|
||
|
C<isl_pw_aff_union_add>.
|
||
|
|
||
|
=item * The C<isl_dim> type has been renamed to C<isl_space>
|
||
|
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<isl_space_params_alloc> or from other spaces using
|
||
|
C<isl_space_params>.
|
||
|
|
||
|
=item * The space in which C<isl_aff>, C<isl_pw_aff>, C<isl_qpolynomial>,
|
||
|
C<isl_pw_qpolynomial>, C<isl_qpolynomial_fold> and C<isl_pw_qpolynomial_fold>
|
||
|
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<isl_aff> are now considered to be of type
|
||
|
C<isl_dim_in> instead of C<isl_dim_set>. 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<isl_equality_alloc> and C<isl_inequality_alloc>
|
||
|
now take an C<isl_local_space> instead of an C<isl_space>.
|
||
|
An C<isl_local_space> can be created from an C<isl_space>
|
||
|
using C<isl_local_space_from_space>.
|
||
|
|
||
|
=item * The C<isl_div> type has been removed. Functions that used
|
||
|
to return an C<isl_div> now return an C<isl_aff>.
|
||
|
Note that the space of an C<isl_aff> is that of relation.
|
||
|
When replacing a call to C<isl_div_get_coefficient> by a call to
|
||
|
C<isl_aff_get_coefficient> any C<isl_dim_set> argument needs
|
||
|
to be replaced by C<isl_dim_in>.
|
||
|
A call to C<isl_aff_from_div> can be replaced by a call
|
||
|
to C<isl_aff_floor>.
|
||
|
A call to C<isl_qpolynomial_div(div)> call be replaced by
|
||
|
the nested call
|
||
|
|
||
|
isl_qpolynomial_from_aff(isl_aff_floor(div))
|
||
|
|
||
|
The function C<isl_constraint_div> has also been renamed
|
||
|
to C<isl_constraint_get_div>.
|
||
|
|
||
|
=item * The C<nparam> argument has been removed from
|
||
|
C<isl_map_read_from_str> 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<schedule_split_parallel> option has been replaced
|
||
|
by the C<schedule_split_scaled> option.
|
||
|
|
||
|
=item * The first argument of C<isl_pw_aff_cond> is now
|
||
|
an C<isl_pw_aff> instead of an C<isl_set>.
|
||
|
A call C<isl_pw_aff_cond(a, b, 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<isl_set_dim_has_lower_bound> and
|
||
|
C<isl_set_dim_has_upper_bound> have been renamed to
|
||
|
C<isl_set_dim_has_any_lower_bound> and
|
||
|
C<isl_set_dim_has_any_upper_bound>.
|
||
|
The new C<isl_set_dim_has_lower_bound> and
|
||
|
C<isl_set_dim_has_upper_bound> have slightly different meanings.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head3 Changes since isl-0.12
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item * C<isl_int> has been replaced by C<isl_val>.
|
||
|
Some of the old functions are still available in C<isl/deprecated/*.h>
|
||
|
but they will be removed in the future.
|
||
|
|
||
|
=item * The functions C<isl_pw_qpolynomial_eval>,
|
||
|
C<isl_union_pw_qpolynomial_eval>, C<isl_pw_qpolynomial_fold_eval>
|
||
|
and C<isl_union_pw_qpolynomial_fold_eval> have been changed to return
|
||
|
an C<isl_val> instead of an C<isl_qpolynomial>.
|
||
|
|
||
|
=item * The function C<isl_band_member_is_zero_distance>
|
||
|
has been removed. Essentially the same functionality is available
|
||
|
through C<isl_band_member_is_coincident>, except that it requires
|
||
|
setting up coincidence constraints.
|
||
|
The option C<schedule_outer_zero_distance> has accordingly been
|
||
|
replaced by the option C<schedule_outer_coincidence>.
|
||
|
|
||
|
=item * The function C<isl_vertex_get_expr> has been changed
|
||
|
to return an C<isl_multi_aff> instead of a rational C<isl_basic_set>.
|
||
|
The function C<isl_vertex_get_domain> 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<isl_union_pw_multi_aff_add> now consistently
|
||
|
computes the sum on the shared definition domain.
|
||
|
The function C<isl_union_pw_multi_aff_union_add> has been added
|
||
|
to compute the sum on the union of definition domains.
|
||
|
The original behavior of C<isl_union_pw_multi_aff_add> was
|
||
|
confused and is no longer available.
|
||
|
|
||
|
=item * Band forests have been replaced by schedule trees.
|
||
|
|
||
|
=item * The function C<isl_union_map_compute_flow> has been
|
||
|
replaced by the function C<isl_union_access_info_compute_flow>.
|
||
|
Note that the may dependence relation returned by
|
||
|
C<isl_union_flow_get_may_dependence> is the union of
|
||
|
the two dependence relations returned by
|
||
|
C<isl_union_map_compute_flow>. Similarly for the no source relations.
|
||
|
The function C<isl_union_map_compute_flow> is still available
|
||
|
for backward compatibility, but it will be removed in the future.
|
||
|
|
||
|
=item * The function C<isl_basic_set_drop_constraint> has been
|
||
|
deprecated.
|
||
|
|
||
|
=item * The function C<isl_ast_build_ast_from_schedule> has been
|
||
|
renamed to C<isl_ast_build_node_from_schedule_map>.
|
||
|
The original name is still available
|
||
|
for backward compatibility, but it will be removed in the future.
|
||
|
|
||
|
=item * The C<separation_class> AST generation option has been
|
||
|
deprecated.
|
||
|
|
||
|
=item * The functions C<isl_equality_alloc> and C<isl_inequality_alloc>
|
||
|
have been renamed to C<isl_constraint_alloc_equality> and
|
||
|
C<isl_constraint_alloc_inequality>. The original names have been
|
||
|
kept for backward compatibility, but they will be removed in the future.
|
||
|
|
||
|
=item * The C<schedule_fuse> option has been replaced
|
||
|
by the C<schedule_serialize_sccs> option. The effect
|
||
|
of setting the C<schedule_fuse> option to C<ISL_SCHEDULE_FUSE_MIN>
|
||
|
is now obtained by turning on the C<schedule_serialize_sccs> option.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head3 Changes since isl-0.17
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item * The function C<isl_printer_print_ast_expr> 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<ISL_FORMAT_C>.
|
||
|
As a result, the function C<isl_ast_expr_to_str> no longer prints
|
||
|
the expression in C format. Use C<isl_ast_expr_to_C_str> instead.
|
||
|
|
||
|
=item * The functions C<isl_set_align_divs> and C<isl_map_align_divs>
|
||
|
have been deprecated. The function C<isl_set_lift> has an effect
|
||
|
that is similar to C<isl_set_align_divs> and could in some cases
|
||
|
be used as an alternative.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head1 License
|
||
|
|
||
|
C<isl> 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<isl> requires C<GMP>, which is released
|
||
|
under the GNU Lesser General Public License (LGPL). This means
|
||
|
that code linked against C<isl> is also linked against LGPL code.
|
||
|
|
||
|
When configuring with C<--with-int=imath> or C<--with-int=imath-32>, C<isl>
|
||
|
will link against C<imath>, a library for exact integer arithmetic released
|
||
|
under the MIT license.
|
||
|
|
||
|
=head1 Installation
|
||
|
|
||
|
The source of C<isl> can be obtained either as a tarball
|
||
|
or from the git repository. Both are available from
|
||
|
L<http://isl.gforge.inria.fr/>.
|
||
|
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<imath> submodule
|
||
|
|
||
|
To build C<isl> with C<imath>, you need to obtain the C<imath>
|
||
|
submodule by running in the git source tree of C<isl>
|
||
|
|
||
|
git submodule init
|
||
|
git submodule update
|
||
|
|
||
|
This will fetch the required version of C<imath> in a subdirectory of C<isl>.
|
||
|
|
||
|
=item 2 Generate C<configure>
|
||
|
|
||
|
./autogen.sh
|
||
|
|
||
|
=back
|
||
|
|
||
|
After performing the above steps, continue
|
||
|
with the L<Common installation instructions>.
|
||
|
|
||
|
=head2 Common installation instructions
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item 1 Obtain C<GMP>
|
||
|
|
||
|
By default, building C<isl> requires C<GMP>, including its headers files.
|
||
|
Your distribution may not provide these header files by default
|
||
|
and you may need to install a package called C<gmp-devel> or something
|
||
|
similar. Alternatively, C<GMP> can be built from
|
||
|
source, available from L<http://gmplib.org/>.
|
||
|
C<GMP> is not needed if you build C<isl> with C<imath>.
|
||
|
|
||
|
=item 2 Configure
|
||
|
|
||
|
C<isl> uses the standard C<autoconf> C<configure> 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<isl>
|
||
|
|
||
|
=item C<--with-int=[gmp|imath|imath-32]>
|
||
|
|
||
|
Select the integer library to be used by C<isl>, the default is C<gmp>.
|
||
|
With C<imath-32>, C<isl> will use 32 bit integers, but fall back to C<imath>
|
||
|
for values out of the 32 bit range. In most applications, C<isl> will run
|
||
|
fastest with the C<imath-32> option, followed by C<gmp> and C<imath>, the
|
||
|
slowest.
|
||
|
|
||
|
=item C<--with-gmp-prefix>
|
||
|
|
||
|
Installation prefix for C<GMP> (architecture-independent files).
|
||
|
|
||
|
=item C<--with-gmp-exec-prefix>
|
||
|
|
||
|
Installation prefix for C<GMP> (architecture-dependent files).
|
||
|
|
||
|
=back
|
||
|
|
||
|
=item 3 Compile
|
||
|
|
||
|
make
|
||
|
|
||
|
=item 4 Install (optional)
|
||
|
|
||
|
make install
|
||
|
|
||
|
=back
|
||
|
|
||
|
=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<NULL>. Is this case, the user
|
||
|
is free to use it as an C<__isl_take> argument or not.
|
||
|
When applied to a C<char *>, the returned pointer needs to be
|
||
|
freed using C<free>.
|
||
|
|
||
|
=item C<__isl_null>
|
||
|
|
||
|
C<__isl_null> means that a C<NULL> 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<NULL> 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<NULL> value will be treated in the same way as
|
||
|
a C<NULL> value for an C<__isl_take> argument.
|
||
|
This annotation may also be used on return values of
|
||
|
type C<const char *>, 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<isl_ctx>.
|
||
|
A given C<isl_ctx> 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<isl_ctx> to another C<isl_ctx>. This means that
|
||
|
there is currently no way of safely moving an object from one
|
||
|
thread to another, unless the whole C<isl_ctx> is moved.
|
||
|
|
||
|
An C<isl_ctx> can be allocated using C<isl_ctx_alloc> and
|
||
|
freed using C<isl_ctx_free>.
|
||
|
All objects allocated within an C<isl_ctx> should be freed
|
||
|
before the C<isl_ctx> 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<operations>
|
||
|
that can be performed by an C<isl_ctx>. 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<isl_ctx_reset_operations>. Note that the number
|
||
|
of low-level operations needed to perform a high-level computation
|
||
|
may differ significantly across different versions
|
||
|
of C<isl>, but it should be the same across different platforms
|
||
|
for the same version of C<isl>.
|
||
|
|
||
|
Warning: This feature is experimental. C<isl> 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/val.h>
|
||
|
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/id.h>
|
||
|
isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id);
|
||
|
|
||
|
#include <isl/local_space.h>
|
||
|
isl_ctx *isl_local_space_get_ctx(
|
||
|
__isl_keep isl_local_space *ls);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
isl_ctx *isl_set_list_get_ctx(
|
||
|
__isl_keep isl_set_list *list);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
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/id_to_ast_expr.h>
|
||
|
isl_ctx *isl_id_to_ast_expr_get_ctx(
|
||
|
__isl_keep isl_id_to_ast_expr *id2expr);
|
||
|
|
||
|
#include <isl/point.h>
|
||
|
isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt);
|
||
|
|
||
|
#include <isl/vec.h>
|
||
|
isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec);
|
||
|
|
||
|
#include <isl/mat.h>
|
||
|
isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat);
|
||
|
|
||
|
#include <isl/vertices.h>
|
||
|
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/flow.h>
|
||
|
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/schedule.h>
|
||
|
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/schedule_node.h>
|
||
|
isl_ctx *isl_schedule_node_get_ctx(
|
||
|
__isl_keep isl_schedule_node *node);
|
||
|
|
||
|
#include <isl/band.h>
|
||
|
isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band);
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
isl_ctx *isl_ast_build_get_ctx(
|
||
|
__isl_keep isl_ast_build *build);
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
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);
|
||
|
|
||
|
=head2 Return Types
|
||
|
|
||
|
C<isl> uses two special return types for functions that either return
|
||
|
a boolean or that in principle do not return anything.
|
||
|
In particular, the C<isl_bool> type has three possible values:
|
||
|
C<isl_bool_true> (a positive integer value), indicating I<true> or I<yes>;
|
||
|
C<isl_bool_false> (the integer value zero), indicating I<false> or I<no>; and
|
||
|
C<isl_bool_error> (a negative integer value), indicating that something
|
||
|
went wrong. The following function can be used to negate an C<isl_bool>,
|
||
|
where the negation of C<isl_bool_error> is C<isl_bool_error> again.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
isl_bool isl_bool_not(isl_bool b);
|
||
|
|
||
|
The C<isl_stat> type has two possible values:
|
||
|
C<isl_stat_ok> (the integer value zero), indicating a successful
|
||
|
operation; and
|
||
|
C<isl_stat_error> (a negative integer value), indicating that something
|
||
|
went wrong.
|
||
|
See L</"Error Handling"> for more information on
|
||
|
C<isl_bool_error> and C<isl_stat_error>.
|
||
|
|
||
|
=head2 Values
|
||
|
|
||
|
An C<isl_val> 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/val.h>
|
||
|
__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/val.h>
|
||
|
__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<isl_val_int_from_chunks> constructs an C<isl_val>
|
||
|
from the C<n> I<digits>, each consisting of C<size> bytes, stored at C<chunks>.
|
||
|
The least significant digit is assumed to be stored first.
|
||
|
|
||
|
Value objects can be copied and freed using the following functions.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__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 <isl/val.h>
|
||
|
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);
|
||
|
size_t isl_val_n_abs_num_chunks(__isl_keep isl_val *v,
|
||
|
size_t size);
|
||
|
int isl_val_get_abs_num_chunks(__isl_keep isl_val *v,
|
||
|
size_t size, void *chunks);
|
||
|
|
||
|
C<isl_val_n_abs_num_chunks> returns the number of I<digits>
|
||
|
of C<size> bytes needed to store the absolute value of the
|
||
|
numerator of C<v>.
|
||
|
C<isl_val_get_abs_num_chunks> stores these digits at C<chunks>,
|
||
|
which is assumed to have been preallocated by the caller.
|
||
|
The least significant digit is stored first.
|
||
|
Note that C<isl_val_get_num_si>, C<isl_val_get_den_si>,
|
||
|
C<isl_val_get_d>, C<isl_val_n_abs_num_chunks>
|
||
|
and C<isl_val_get_abs_num_chunks> can only be applied to rational values.
|
||
|
|
||
|
An C<isl_val> can be modified using the following function.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__isl_give isl_val *isl_val_set_si(__isl_take isl_val *v,
|
||
|
long i);
|
||
|
|
||
|
The following unary properties are defined on C<isl_val>s.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
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 C<isl_val>s.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
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<isl_val_abs_eq> checks whether its two arguments
|
||
|
are equal in absolute value.
|
||
|
|
||
|
For integer C<isl_val>s we additionally have the following binary property.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1,
|
||
|
__isl_keep isl_val *v2);
|
||
|
|
||
|
An C<isl_val> can also be compared to an integer using the following
|
||
|
function. The result is undefined for NaN.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
int isl_val_cmp_si(__isl_keep isl_val *v, long i);
|
||
|
|
||
|
The following unary operations are available on C<isl_val>s.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__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);
|
||
|
__isl_give isl_val *isl_val_2exp(__isl_take isl_val *v);
|
||
|
|
||
|
The following binary operations are available on C<isl_val>s.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__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/val.h>
|
||
|
__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);
|
||
|
|
||
|
The function C<isl_val_gcdext> returns the greatest common divisor g
|
||
|
of C<v1> and C<v2> as well as two integers C<*x> and C<*y> such
|
||
|
that C<*x> * C<v1> + C<*y> * C<v2> = g.
|
||
|
|
||
|
=head3 GMP specific functions
|
||
|
|
||
|
These functions are only available if C<isl> has been compiled with C<GMP>
|
||
|
support.
|
||
|
|
||
|
Specific integer and rational values can be created from C<GMP> values using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/val_gmp.h>
|
||
|
__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<GMP> values using the following functions.
|
||
|
|
||
|
#include <isl/val_gmp.h>
|
||
|
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<isl> uses six types of objects for representing sets and relations,
|
||
|
C<isl_basic_set>, C<isl_basic_map>, C<isl_set>, C<isl_map>,
|
||
|
C<isl_union_set> and C<isl_union_map>.
|
||
|
C<isl_basic_set> and C<isl_basic_map> represent sets and relations that
|
||
|
can be described as a conjunction of affine constraints, while
|
||
|
C<isl_set> and C<isl_map> represent unions of
|
||
|
C<isl_basic_set>s and C<isl_basic_map>s, respectively.
|
||
|
However, all C<isl_basic_set>s or C<isl_basic_map>s in the union need
|
||
|
to live in the same space. C<isl_union_set>s and C<isl_union_map>s
|
||
|
represent unions of C<isl_set>s or C<isl_map>s in I<different> 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<isl> supports different ways to react in case a runtime error is triggered.
|
||
|
Runtime errors arise, e.g., if a function such as C<isl_map_intersect> 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<isl> prints a warning, stores
|
||
|
the last error in the corresponding C<isl_ctx> and the function in which the
|
||
|
error was triggered returns a value indicating that some error has
|
||
|
occurred. In case of functions returning a pointer, this value is
|
||
|
C<NULL>. In case of functions returning an C<isl_bool> or an
|
||
|
C<isl_stat>, this valus is C<isl_bool_error> or C<isl_stat_error>.
|
||
|
An error does not corrupt internal state,
|
||
|
such that isl can continue to be used. C<isl> also provides functions to
|
||
|
read the last error and to reset the memory that stores the last error. The
|
||
|
last error is only stored for information purposes. Its presence does not
|
||
|
change the behavior of C<isl>. Hence, resetting an error is not required to
|
||
|
continue to use isl, but only to observe new errors.
|
||
|
|
||
|
#include <isl/ctx.h>
|
||
|
enum isl_error isl_ctx_last_error(isl_ctx *ctx);
|
||
|
void isl_ctx_reset_error(isl_ctx *ctx);
|
||
|
|
||
|
Another option is to continue on error. This is similar to warn on error mode,
|
||
|
except that C<isl> does not print any warning. This allows a program to
|
||
|
implement its own error reporting.
|
||
|
|
||
|
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<isl_options_set_on_error> or by setting the command line option
|
||
|
C<--isl-on-error>. Valid arguments for the function call are
|
||
|
C<ISL_ON_ERROR_WARN>, C<ISL_ON_ERROR_CONTINUE> and C<ISL_ON_ERROR_ABORT>. The
|
||
|
choices for the command line option are C<warn>, C<continue> and C<abort>.
|
||
|
It is also possible to query the current error mode.
|
||
|
|
||
|
#include <isl/options.h>
|
||
|
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<NULL>, 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/id.h>
|
||
|
__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));
|
||
|
__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<isl_id_set_free_user> is called on the user
|
||
|
pointer when the last reference to the C<isl_id> is freed.
|
||
|
Note that C<isl_id_get_name> returns a pointer to some internal
|
||
|
data structure, so the result can only be used while the
|
||
|
corresponding C<isl_id> 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<isl_space>.
|
||
|
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<isl_dim_type> and a position.
|
||
|
The type C<isl_dim_param> refers to parameters,
|
||
|
the type C<isl_dim_set> refers to set dimensions (for spaces
|
||
|
with a single tuple of dimensions) and the types C<isl_dim_in>
|
||
|
and C<isl_dim_out> refer to input and output dimensions
|
||
|
(for spaces with two tuples of dimensions).
|
||
|
Local spaces (see L</"Local Spaces">) also contain dimensions
|
||
|
of type C<isl_dim_div>.
|
||
|
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/space.h>
|
||
|
__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<isl_space_params_alloc>.
|
||
|
For other sets, the space
|
||
|
needs to be created using C<isl_space_set_alloc>, while
|
||
|
for a relation, the space
|
||
|
needs to be created using C<isl_space_alloc>.
|
||
|
|
||
|
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/space.h>
|
||
|
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/space.h>
|
||
|
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<isl_space_is_domain> 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<isl_space_tuple_is_equal> checks whether the given
|
||
|
tuples (C<isl_dim_in>, C<isl_dim_out> or C<isl_dim_set>) 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<isl_space_has_equal_params> checks whether two spaces
|
||
|
have the same parameters in the same order.
|
||
|
C<isl_space_has_equal_tuples> check whether two spaces have
|
||
|
the same tuples. In contrast to C<isl_space_is_equal> below,
|
||
|
it does not check the
|
||
|
parameters. This is useful because many C<isl> functions align the
|
||
|
parameters before they perform their operations, such that equivalence
|
||
|
is not necessary.
|
||
|
C<isl_space_is_equal> checks whether two spaces are identical,
|
||
|
meaning that they have the same parameters and the same tuples.
|
||
|
That is, it checks whether both C<isl_space_has_equal_params> and
|
||
|
C<isl_space_has_equal_tuples> 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</"Creating New Sets and Relations"> or
|
||
|
L</"Functions">) based on the space
|
||
|
of the original object.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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/union_set.h>
|
||
|
__isl_give isl_space *isl_union_set_get_space(
|
||
|
__isl_keep isl_union_set *uset);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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/union_map.h>
|
||
|
__isl_give isl_space *isl_union_map_get_space(
|
||
|
__isl_keep isl_union_map *umap);
|
||
|
|
||
|
#include <isl/constraint.h>
|
||
|
__isl_give isl_space *isl_constraint_get_space(
|
||
|
__isl_keep isl_constraint *constraint);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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/val.h>
|
||
|
__isl_give isl_space *isl_multi_val_get_space(
|
||
|
__isl_keep isl_multi_val *mv);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/point.h>
|
||
|
__isl_give isl_space *isl_point_get_space(
|
||
|
__isl_keep isl_point *pnt);
|
||
|
|
||
|
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<isl_space_dim>, type may be
|
||
|
C<isl_dim_param>, C<isl_dim_in> (only for relations),
|
||
|
C<isl_dim_out> (only for relations), C<isl_dim_set>
|
||
|
(only for sets) or C<isl_dim_all>.
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
unsigned isl_space_dim(__isl_keep isl_space *space,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
#include <isl/local_space.h>
|
||
|
int isl_local_space_dim(__isl_keep isl_local_space *ls,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
unsigned isl_basic_set_dim(__isl_keep isl_basic_set *bset,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_set_dim(__isl_keep isl_set *set,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
#include <isl/union_set.h>
|
||
|
unsigned isl_union_set_dim(__isl_keep isl_union_set *uset,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
unsigned isl_basic_map_dim(__isl_keep isl_basic_map *bmap,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_map_dim(__isl_keep isl_map *map,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
unsigned isl_union_map_dim(__isl_keep isl_union_map *umap,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
unsigned isl_multi_val_dim(__isl_keep isl_multi_val *mv,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
int isl_aff_dim(__isl_keep isl_aff *aff,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_multi_aff_dim(__isl_keep isl_multi_aff *maff,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_pw_aff_dim(__isl_keep isl_pw_aff *pwaff,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_pw_multi_aff_dim(
|
||
|
__isl_keep isl_pw_multi_aff *pma,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_multi_pw_aff_dim(
|
||
|
__isl_keep isl_multi_pw_aff *mpa,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_union_pw_aff_dim(
|
||
|
__isl_keep isl_union_pw_aff *upa,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_union_pw_multi_aff_dim(
|
||
|
__isl_keep isl_union_pw_multi_aff *upma,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_multi_union_pw_aff_dim(
|
||
|
__isl_keep isl_multi_union_pw_aff *mupa,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
unsigned isl_union_pw_qpolynomial_dim(
|
||
|
__isl_keep isl_union_pw_qpolynomial *upwqp,
|
||
|
enum isl_dim_type type);
|
||
|
unsigned isl_union_pw_qpolynomial_fold_dim(
|
||
|
__isl_keep isl_union_pw_qpolynomial_fold *upwf,
|
||
|
enum isl_dim_type type);
|
||
|
|
||
|
Note that an C<isl_union_set>, an C<isl_union_map>,
|
||
|
an C<isl_union_pw_multi_aff>,
|
||
|
an C<isl_union_pw_qpolynomial> and
|
||
|
an C<isl_union_pw_qpolynomial_fold>
|
||
|
only have parameters.
|
||
|
|
||
|
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.
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__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/local_space.h>
|
||
|
__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 <isl/constraint.h>
|
||
|
const char *isl_constraint_get_dim_name(
|
||
|
__isl_keep isl_constraint *constraint,
|
||
|
enum isl_dim_type type, unsigned pos);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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/map.h>
|
||
|
__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/val.h>
|
||
|
__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/aff.h>
|
||
|
__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 *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/polynomial.h>
|
||
|
__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<isl_space_get_name> returns a pointer to some internal
|
||
|
data structure, so the result can only be used while the
|
||
|
corresponding C<isl_space> 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<isl_set>, C<isl_map>, C<isl_union_set> and/or C<isl_union_map>
|
||
|
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 <isl/space.h>
|
||
|
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 <isl/local_space.h>
|
||
|
int isl_local_space_find_dim_by_name(
|
||
|
__isl_keep isl_local_space *ls,
|
||
|
enum isl_dim_type type, const char *name);
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
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 <isl/set.h>
|
||
|
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 <isl/map.h>
|
||
|
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 <isl/aff.h>
|
||
|
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_union_multi_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 <isl/polynomial.h>
|
||
|
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/space.h>
|
||
|
__isl_give isl_space *isl_space_set_tuple_id(
|
||
|
__isl_take isl_space *space,
|
||
|
enum isl_dim_type type, __isl_take isl_id *id);
|
||
|
__isl_give isl_space *isl_space_reset_tuple_id(
|
||
|
__isl_take isl_space *space, enum isl_dim_type type);
|
||
|
isl_bool isl_space_has_tuple_id(
|
||
|
__isl_keep isl_space *space,
|
||
|
enum isl_dim_type type);
|
||
|
__isl_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/local_space.h>
|
||
|
__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/set.h>
|
||
|
__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/map.h>
|
||
|
__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_tuple_id(
|
||
|
__isl_take isl_map *map, enum isl_dim_type type,
|
||
|
__isl_take isl_id *id);
|
||
|
__isl_give isl_map *isl_map_reset_tuple_id(
|
||
|
__isl_take isl_map *map, enum isl_dim_type type);
|
||
|
isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map,
|
||
|
enum isl_dim_type type);
|
||
|
__isl_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/val.h>
|
||
|
__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_tuple_id(
|
||
|
__isl_take isl_multi_val *mv,
|
||
|
enum isl_dim_type type);
|
||
|
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/aff.h>
|
||
|
__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_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_tuple_id(
|
||
|
__isl_take isl_pw_multi_aff *pma,
|
||
|
enum isl_dim_type type, __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_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_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_tuple_id(
|
||
|
__isl_keep isl_pw_multi_aff *pma,
|
||
|
enum isl_dim_type type);
|
||
|
__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_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_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<type> argument needs to be one of C<isl_dim_in>, C<isl_dim_out>
|
||
|
or C<isl_dim_set>. As with C<isl_space_get_name>,
|
||
|
the C<isl_space_get_tuple_name> 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/space.h>
|
||
|
__isl_give isl_space *isl_space_reset_user(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__isl_give isl_set *isl_set_reset_user(
|
||
|
__isl_take isl_set *set);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__isl_give isl_map *isl_map_reset_user(
|
||
|
__isl_take isl_map *map);
|
||
|
|
||
|
#include <isl/union_set.h>
|
||
|
__isl_give isl_union_set *isl_union_set_reset_user(
|
||
|
__isl_take isl_union_set *uset);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__isl_give isl_union_map *isl_union_map_reset_user(
|
||
|
__isl_take isl_union_map *umap);
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__isl_give isl_multi_val *isl_multi_val_reset_user(
|
||
|
__isl_take isl_multi_val *mv);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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<wrapping>.
|
||
|
The functions for detecting, constructing and deconstructing
|
||
|
such nested spaces can be found in the wrapping properties
|
||
|
of L</"Unary Properties">, the wrapping operations
|
||
|
of L</"Unary Operations"> and the Cartesian product operations
|
||
|
of L</"Basic Operations">.
|
||
|
|
||
|
Spaces can be created from other spaces
|
||
|
using the functions described in L</"Unary Operations">
|
||
|
and L</"Binary Operations">.
|
||
|
|
||
|
=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/constraint.h>
|
||
|
__isl_give isl_local_space *isl_constraint_get_local_space(
|
||
|
__isl_keep isl_constraint *constraint);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__isl_give isl_local_space *isl_basic_set_get_local_space(
|
||
|
__isl_keep isl_basic_set *bset);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__isl_give isl_local_space *isl_basic_map_get_local_space(
|
||
|
__isl_keep isl_basic_map *bmap);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/local_space.h>
|
||
|
__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/local_space.h>
|
||
|
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<isl_local_space_get_div> 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</"Unary Operations">
|
||
|
and L</"Binary Operations">.
|
||
|
|
||
|
=head2 Creating New Sets and Relations
|
||
|
|
||
|
C<isl> 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(
|
||
|
__isl_take isl_space *space);
|
||
|
__isl_give isl_union_map *isl_union_map_empty(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
For C<isl_union_set>s and C<isl_union_map>s, the space
|
||
|
is only used to specify the parameters.
|
||
|
|
||
|
=item * Universe sets and relations
|
||
|
|
||
|
__isl_give isl_basic_set *isl_basic_set_universe(
|
||
|
__isl_take isl_space *space);
|
||
|
__isl_give isl_basic_map *isl_basic_map_universe(
|
||
|
__isl_take isl_space *space);
|
||
|
__isl_give isl_set *isl_set_universe(
|
||
|
__isl_take isl_space *space);
|
||
|
__isl_give isl_map *isl_map_universe(
|
||
|
__isl_take isl_space *space);
|
||
|
__isl_give isl_union_set *isl_union_set_universe(
|
||
|
__isl_take isl_union_set *uset);
|
||
|
__isl_give isl_union_map *isl_union_map_universe(
|
||
|
__isl_take isl_union_map *umap);
|
||
|
|
||
|
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<space> 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<set>
|
||
|
and return relations that express that the elements in the domain
|
||
|
are lexicographically less
|
||
|
(C<isl_map_lex_lt>), less or equal (C<isl_map_lex_le>),
|
||
|
greater (C<isl_map_lex_gt>) or greater or equal (C<isl_map_lex_ge>)
|
||
|
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<n> dimensions
|
||
|
in the domain are lexicographically less
|
||
|
(C<isl_map_lex_lt_first>), less or equal (C<isl_map_lex_le_first>),
|
||
|
greater (C<isl_map_lex_gt_first>) or greater or equal (C<isl_map_lex_ge_first>)
|
||
|
than the first C<n> 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_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);
|
||
|
|
||
|
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_union_set_from_set(
|
||
|
__isl_take isl_set *set);
|
||
|
__isl_give isl_union_map *isl_union_map_from_map(
|
||
|
__isl_take isl_map *map);
|
||
|
|
||
|
The inverse conversions below can only be used if the input
|
||
|
union set or relation is known to contain elements in exactly one
|
||
|
space.
|
||
|
|
||
|
__isl_give isl_set *isl_set_from_union_set(
|
||
|
__isl_take isl_union_set *uset);
|
||
|
__isl_give isl_map *isl_map_from_union_map(
|
||
|
__isl_take isl_union_map *umap);
|
||
|
|
||
|
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/constraint.h>
|
||
|
__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 would 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);
|
||
|
|
||
|
Or, alternatively,
|
||
|
|
||
|
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<isl_dim_type> arguments indicate the order in which
|
||
|
different kinds of variables appear in the input matrices
|
||
|
and should be a permutation of C<isl_dim_cst>, C<isl_dim_param>,
|
||
|
C<isl_dim_set> and C<isl_dim_div> for sets and
|
||
|
of C<isl_dim_cst>, C<isl_dim_param>,
|
||
|
C<isl_dim_in>, C<isl_dim_out> and C<isl_dim_div> 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</"Functions">), provided these affine expressions do not
|
||
|
involve any NaN.
|
||
|
|
||
|
__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_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_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_map_from_multi_aff(
|
||
|
__isl_take isl_multi_aff *maff)
|
||
|
__isl_give isl_set *isl_set_from_pw_multi_aff(
|
||
|
__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_set_from_multi_pw_aff(
|
||
|
__isl_take isl_multi_pw_aff *mpa);
|
||
|
__isl_give isl_map *isl_map_from_multi_pw_aff(
|
||
|
__isl_take isl_multi_pw_aff *mpa);
|
||
|
__isl_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_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<domain_space> argument describes the domain of the resulting
|
||
|
basic relation. It is required because the C<list> may consist
|
||
|
of zero affine expressions.
|
||
|
The C<mupa> passed to C<isl_union_map_from_multi_union_pw_aff>
|
||
|
is not allowed to be zero-dimensional. The domain of the result
|
||
|
is the shared domain of the union piecewise affine elements.
|
||
|
|
||
|
=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<isl> 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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_set.h>
|
||
|
__isl_give isl_union_set *isl_union_set_remove_divs(
|
||
|
__isl_take isl_union_set *bset);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__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
|
||
|
|
||
|
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_stat isl_union_map_foreach_map(
|
||
|
__isl_keep isl_union_map *umap,
|
||
|
isl_stat (*fn)(__isl_take 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 number of sets or maps in a union set or map can be obtained
|
||
|
from
|
||
|
|
||
|
int isl_union_set_n_set(__isl_keep isl_union_set *uset);
|
||
|
int 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<fn> should return 0 if successful and
|
||
|
-1 if an error occurs. In the latter case, or if any other error
|
||
|
occurs, the above functions will return -1.
|
||
|
|
||
|
It should be noted that C<isl> does not guarantee that
|
||
|
the basic sets or maps passed to C<fn> 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/set.h>
|
||
|
int isl_set_n_basic_set(__isl_keep isl_set *set);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
int 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
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__isl_give isl_basic_set_list *isl_set_get_basic_set_list(
|
||
|
__isl_keep isl_set *set);
|
||
|
|
||
|
#include <isl/union_set.h>
|
||
|
__isl_give isl_basic_set_list *
|
||
|
isl_union_set_get_basic_set_list(
|
||
|
__isl_keep isl_union_set *uset);
|
||
|
|
||
|
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/constraint.h>
|
||
|
|
||
|
int 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);
|
||
|
int 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<fn> should return 0 if successful and
|
||
|
-1 if an error occurs. In the latter case, or if any other error
|
||
|
occurs, the above functions will return -1.
|
||
|
The constraint C<c> represents either an equality or an inequality.
|
||
|
Use the following function to find out whether a constraint
|
||
|
represents an equality. If not, it represents an inequality.
|
||
|
|
||
|
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/constraint.h>
|
||
|
__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<isl_set_compute_divs> or C<isl_map_compute_divs>.
|
||
|
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</"Functions">.
|
||
|
|
||
|
__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<isl_dim_type> 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<isl_dim_cst>, C<isl_dim_param>, C<isl_dim_set> and C<isl_dim_div>.
|
||
|
For map inputs, they should be a permutation of
|
||
|
C<isl_dim_cst>, C<isl_dim_param>,
|
||
|
C<isl_dim_in>, C<isl_dim_out> and C<isl_dim_div>.
|
||
|
|
||
|
=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
|
||
|
|
||
|
__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
|
||
|
|
||
|
__isl_give isl_basic_set *isl_basic_set_from_point(
|
||
|
__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);
|
||
|
|
||
|
and 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<bounded> (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<fn> is called for each integer point in
|
||
|
C<set> with as second argument the last argument of
|
||
|
the C<isl_set_foreach_point> call. The function C<fn>
|
||
|
should return C<0> on success and C<-1> on failure.
|
||
|
In the latter case, C<isl_set_foreach_point> will stop
|
||
|
enumerating and return C<-1> as well.
|
||
|
If the enumeration is performed successfully and to completion,
|
||
|
then C<isl_set_foreach_point> returns C<0>.
|
||
|
|
||
|
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<set> 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<isl> also supports various types of functions.
|
||
|
Each of these types is derived from the value type (see L</"Values">)
|
||
|
or from one of two primitive function types
|
||
|
through the application of zero or more type constructors.
|
||
|
We first describe the primitive type and then we describe
|
||
|
the types derived from these primitive types.
|
||
|
|
||
|
=head3 Primitive Functions
|
||
|
|
||
|
C<isl> 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<x> 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</"Multiple Expressions">).
|
||
|
|
||
|
=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 or
|
||
|
a specified dimension on a given domain can be created using
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_aff *isl_aff_zero_on_domain(
|
||
|
__isl_take isl_local_space *ls);
|
||
|
__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(
|
||
|
__isl_take isl_local_space *ls);
|
||
|
|
||
|
Quasi affine expressions can be copied and freed using
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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<isl_constraint>
|
||
|
using the following function. The constraint is required to have
|
||
|
a non-zero coefficient for the specified dimension.
|
||
|
|
||
|
#include <isl/constraint.h>
|
||
|
__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/constraint.h>
|
||
|
__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/aff.h>
|
||
|
__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/aff.h>
|
||
|
__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<isl_aff_set_constant_si> and C<isl_aff_set_coefficient_si>
|
||
|
set the I<numerator> of the constant or coefficient, while
|
||
|
C<isl_aff_set_constant_val> and C<isl_aff_set_coefficient_val> set
|
||
|
the constant or coefficient as a whole.
|
||
|
The C<add_constant> and C<add_coefficient> functions add an integer
|
||
|
or rational value to
|
||
|
the possibly rational constant or coefficient.
|
||
|
The C<add_constant_num> functions add an integer value to
|
||
|
the numerator.
|
||
|
|
||
|
=item * Quasipolynomials
|
||
|
|
||
|
Some simple quasipolynomials can be created using the following functions.
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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<domain> 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/polynomial.h>
|
||
|
__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
|
||
|
|
||
|
unsigned 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);
|
||
|
int 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);
|
||
|
void isl_term_free(__isl_take isl_term *term);
|
||
|
|
||
|
Each term is a product of parameters, set variables and
|
||
|
integer divisions. The function C<isl_term_get_exp>
|
||
|
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<isl> is
|
||
|
C<isl_qpolynomial_fold>.
|
||
|
|
||
|
There are currently no functions to directly create such
|
||
|
objects, but they do appear in the piecewise quasipolynomial
|
||
|
reductions returned by the C<isl_pw_qpolynomial_bound> function.
|
||
|
See
|
||
|
L</"Bounds on Piecewise Quasipolynomials and Piecewise Quasipolynomial Reductions">.
|
||
|
|
||
|
Reductions can be copied and freed using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__isl_give isl_qpolynomial_fold *
|
||
|
isl_qpolynomial_fold_copy(
|
||
|
__isl_keep isl_qpolynomial_fold *fold);
|
||
|
void isl_qpolynomial_fold_free(
|
||
|
__isl_take isl_qpolynomial_fold *fold);
|
||
|
|
||
|
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 type do not have an associated space.
|
||
|
The space of a multiple value is therefore always a set space.
|
||
|
Similarly, the space of a multiple union piecewise
|
||
|
affine expression is always a set space.
|
||
|
|
||
|
The multiple expression types defined by C<isl>
|
||
|
are C<isl_multi_val>, C<isl_multi_aff>, C<isl_multi_pw_aff>,
|
||
|
C<isl_multi_union_pw_aff>.
|
||
|
|
||
|
A multiple expression with the value zero for
|
||
|
each output (or set) dimension can be created
|
||
|
using the following functions.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__isl_give isl_multi_val *isl_multi_val_zero(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_multi_aff *isl_multi_aff_zero(
|
||
|
__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_union_pw_aff *
|
||
|
isl_multi_union_pw_aff_zero(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
Since there is no canonical way of representing a zero
|
||
|
value of type C<isl_union_pw_aff>, the space passed
|
||
|
to C<isl_multi_union_pw_aff_zero> needs to be zero-dimensional.
|
||
|
|
||
|
An identity function can be created using the following
|
||
|
functions. The space needs to be that of a relation
|
||
|
with the same number of input and output dimensions.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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);
|
||
|
|
||
|
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</"Unary Operations">.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_multi_aff *isl_multi_aff_domain_map(
|
||
|
__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_multi_aff_project_out_map(
|
||
|
__isl_take isl_space *space,
|
||
|
enum isl_dim_type type,
|
||
|
unsigned first, unsigned n);
|
||
|
|
||
|
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<isl_multi_union_pw_aff_from_union_pw_aff> where the input
|
||
|
lives in a parameter space and the output lives
|
||
|
in a single-dimensional set space.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/val.h>
|
||
|
__isl_give isl_multi_val *isl_multi_val_from_val_list(
|
||
|
__isl_take isl_space *space,
|
||
|
__isl_take isl_val_list *list);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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_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_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);
|
||
|
|
||
|
As a convenience, a multiple piecewise expression can
|
||
|
also be created from a multiple expression.
|
||
|
Each piecewise expression in the result has a single
|
||
|
universe cell.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_multi_pw_aff *
|
||
|
isl_multi_pw_aff_from_multi_aff(
|
||
|
__isl_take isl_multi_aff *ma);
|
||
|
|
||
|
Similarly, a multiple union expression can be
|
||
|
created from a multiple expression.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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_union_pw_aff_from_multi_pw_aff(
|
||
|
__isl_take isl_multi_pw_aff *mpa);
|
||
|
|
||
|
A multiple quasi-affine expression can be created from
|
||
|
a multiple value with a given domain space using the following
|
||
|
function.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_multi_aff *
|
||
|
isl_multi_aff_multi_val_on_space(
|
||
|
__isl_take isl_space *space,
|
||
|
__isl_take isl_multi_val *mv);
|
||
|
|
||
|
Similarly,
|
||
|
a multiple union piecewise affine expression can be created from
|
||
|
a multiple value with a given domain or
|
||
|
a multiple affine expression with a given domain
|
||
|
using the following functions.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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);
|
||
|
|
||
|
Multiple expressions can be copied and freed using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__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/aff.h>
|
||
|
__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 base expression at a given position of a multiple
|
||
|
expression can be extracted using the following functions.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__isl_give isl_val *isl_multi_val_get_val(
|
||
|
__isl_keep isl_multi_val *mv, int pos);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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_pw_aff(
|
||
|
__isl_keep isl_multi_pw_aff *mpa, 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);
|
||
|
|
||
|
It can be replaced using the following functions.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__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/aff.h>
|
||
|
__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_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);
|
||
|
|
||
|
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/aff.h>
|
||
|
__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<isl_multi_union_pw_aff>
|
||
|
and C<isl_union_pw_multi_aff> 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<isl_union_pw_multi_aff> may live in different spaces,
|
||
|
while there is only a single multiple expression in
|
||
|
an C<isl_multi_union_pw_aff>, which can therefore only live
|
||
|
in a single space. This means that not every
|
||
|
C<isl_union_pw_multi_aff> can be converted to
|
||
|
an C<isl_multi_union_pw_aff>. Conversely, a zero-dimensional
|
||
|
C<isl_multi_union_pw_aff> carries no information
|
||
|
about any possible domain and therefore cannot be converted
|
||
|
to an C<isl_union_pw_multi_aff>. Moreover, the elements
|
||
|
of an C<isl_multi_union_pw_aff> may be defined over different domains,
|
||
|
while each multiple expression inside an C<isl_union_pw_multi_aff>
|
||
|
has a single domain. The conversion of an C<isl_union_pw_multi_aff>
|
||
|
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/aff.h>
|
||
|
__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);
|
||
|
|
||
|
=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<barvinok>
|
||
|
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<isl>
|
||
|
are C<isl_pw_aff>, C<isl_pw_multi_aff>,
|
||
|
C<isl_pw_qpolynomial> and C<isl_pw_qpolynomial_fold>.
|
||
|
|
||
|
A piecewise expression with no cells can be created using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/aff.h>
|
||
|
__isl_give isl_pw_aff *isl_pw_aff_from_aff(
|
||
|
__isl_take isl_aff *aff);
|
||
|
__isl_give isl_pw_multi_aff *
|
||
|
isl_pw_multi_aff_from_multi_aff(
|
||
|
__isl_take isl_multi_aff *ma);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__isl_give isl_pw_qpolynomial *
|
||
|
isl_pw_qpolynomial_from_qpolynomial(
|
||
|
__isl_take isl_qpolynomial *qp);
|
||
|
|
||
|
A piecewise expression with a single specified cell can be
|
||
|
created using the following functions.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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/aff.h>
|
||
|
__isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(
|
||
|
__isl_take isl_local_space *ls);
|
||
|
__isl_give isl_pw_aff *isl_pw_aff_var_on_domain(
|
||
|
__isl_take isl_local_space *ls,
|
||
|
enum isl_dim_type type, unsigned pos);
|
||
|
__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(
|
||
|
__isl_take isl_local_space *ls);
|
||
|
__isl_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(
|
||
|
__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_pw_multi_aff_project_out_map(
|
||
|
__isl_take isl_space *space,
|
||
|
enum isl_dim_type type,
|
||
|
unsigned first, unsigned n);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_zero(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
The following convenience functions first create a base expression and
|
||
|
then create a piecewise expression over a given domain.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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_multi_aff *
|
||
|
isl_pw_multi_aff_multi_val_on_domain(
|
||
|
__isl_take isl_set *domain,
|
||
|
__isl_take isl_multi_val *mv);
|
||
|
|
||
|
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/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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/aff.h>
|
||
|
isl_bool isl_pw_aff_is_empty(__isl_keep isl_pw_aff *pwaff);
|
||
|
int 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);
|
||
|
int 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);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
int 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_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);
|
||
|
int 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_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<fn> should return C<0> on success
|
||
|
and C<-1> on failure. The difference between
|
||
|
C<isl_pw_qpolynomial_foreach_piece> and
|
||
|
C<isl_pw_qpolynomial_foreach_lifted_piece> is that
|
||
|
C<isl_pw_qpolynomial_foreach_lifted_piece> will first
|
||
|
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<set> passed to C<fn>
|
||
|
will not have any existentially quantified variables, but that
|
||
|
the dimensions of the sets may be different for different
|
||
|
invocations of C<fn>.
|
||
|
Similarly for C<isl_pw_qpolynomial_fold_foreach_piece>
|
||
|
and C<isl_pw_qpolynomial_fold_foreach_lifted_piece>.
|
||
|
|
||
|
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/aff.h>
|
||
|
__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
|
||
|
__isl_keep isl_pw_multi_aff *pma, int pos);
|
||
|
|
||
|
These expressions can be replaced using the following function.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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<isl_multi_pw_aff> and
|
||
|
C<isl_pw_multi_aff> 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<isl_multi_pw_aff> may have a different
|
||
|
domain, while all multiple expressions associated to a cell
|
||
|
in an C<isl_pw_multi_aff> have the same domain.
|
||
|
It is possible to convert between the two, but when converting
|
||
|
an C<isl_multi_pw_aff> to an C<isl_pw_multi_aff>, the domain
|
||
|
of the result is the intersection of the domains of the input.
|
||
|
The reverse conversion is exact.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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_multi_pw_aff_from_pw_multi_aff(
|
||
|
__isl_take isl_pw_multi_aff *pma);
|
||
|
|
||
|
=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<isl>
|
||
|
are C<isl_union_pw_aff>, C<isl_union_pw_multi_aff>,
|
||
|
C<isl_union_pw_qpolynomial> and C<isl_union_pw_qpolynomial_fold>.
|
||
|
In case of
|
||
|
C<isl_union_pw_aff>,
|
||
|
C<isl_union_pw_qpolynomial> and C<isl_union_pw_qpolynomial_fold>,
|
||
|
there can be at most one base expression for a given domain space.
|
||
|
In case of
|
||
|
C<isl_union_pw_multi_aff>,
|
||
|
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/aff.h>
|
||
|
__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(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__isl_give isl_union_pw_qpolynomial *
|
||
|
isl_union_pw_qpolynomial_zero(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
A union expression containing a single base expression
|
||
|
can be created using the following functions.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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_union_pw_multi_aff_from_pw_multi_aff(
|
||
|
__isl_take isl_pw_multi_aff *pma);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__isl_give isl_union_pw_qpolynomial *
|
||
|
isl_union_pw_qpolynomial_from_pw_qpolynomial(
|
||
|
__isl_take isl_pw_qpolynomial *pwqp);
|
||
|
|
||
|
The following functions create a base expression on each
|
||
|
of the sets in the union set and collect the results.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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);
|
||
|
|
||
|
An C<isl_union_pw_aff> that is equal to a (parametric) affine
|
||
|
expression on a given domain can be created using the following
|
||
|
function.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_union_pw_aff *
|
||
|
isl_union_pw_aff_aff_on_domain(
|
||
|
__isl_take isl_union_set *domain,
|
||
|
__isl_take isl_aff *aff);
|
||
|
|
||
|
A base expression can be added to a union expression using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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/aff.h>
|
||
|
int 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);
|
||
|
int 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);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
int 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);
|
||
|
int 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);
|
||
|
|
||
|
To extract the base expression in a given space from a union, use
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__isl_give isl_pw_qpolynomial *
|
||
|
isl_union_pw_qpolynomial_extract_pw_qpolynomial(
|
||
|
__isl_keep isl_union_pw_qpolynomial *upwqp,
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
=head2 Input and Output
|
||
|
|
||
|
For set and relation,
|
||
|
C<isl> supports its own input/output format, which is similar
|
||
|
to the C<Omega> format, but also supports the C<PolyLib> format
|
||
|
in some cases.
|
||
|
For other object types, typically only an C<isl> format is supported.
|
||
|
|
||
|
=head3 C<isl> format
|
||
|
|
||
|
The C<isl> format is similar to that of C<Omega>, 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<i> between C<0> and C<n>
|
||
|
such that C<i % 10 <= 6> 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<or>. Each disjunct is either a conjunction
|
||
|
of constraints or a projection (C<exists>) of a conjunction
|
||
|
of constraints. The constraints are separated by the keyword
|
||
|
C<and>.
|
||
|
|
||
|
=head3 C<PolyLib> 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<PolyLib> format
|
||
|
|
||
|
The extended C<PolyLib> format is nearly identical to the
|
||
|
C<PolyLib> 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/val.h>
|
||
|
__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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_set.h>
|
||
|
__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/union_map.h>
|
||
|
__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/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__isl_give isl_union_pw_qpolynomial *
|
||
|
isl_union_pw_qpolynomial_read_from_str(
|
||
|
isl_ctx *ctx, const char *str);
|
||
|
|
||
|
For sets and relations,
|
||
|
the input format is autodetected and may be either the C<PolyLib> format
|
||
|
or the C<isl> format.
|
||
|
|
||
|
=head3 Output
|
||
|
|
||
|
Before anything can be printed, an C<isl_printer> 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<isl_printer_to_file> prints to the given file, while
|
||
|
C<isl_printer_to_str> prints to a string that can be extracted
|
||
|
using the following function.
|
||
|
|
||
|
#include <isl/printer.h>
|
||
|
__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<output_format> may be either C<ISL_FORMAT_ISL>, C<ISL_FORMAT_OMEGA>,
|
||
|
C<ISL_FORMAT_POLYLIB>, C<ISL_FORMAT_EXT_POLYLIB> or C<ISL_FORMAT_LATEX>
|
||
|
and defaults to C<ISL_FORMAT_ISL>.
|
||
|
Each line in the output is prefixed by C<indent_prefix>,
|
||
|
indented by C<indent> (set by C<isl_printer_set_indent>) spaces
|
||
|
(default: 0), prefixed by C<prefix> and suffixed by C<suffix>.
|
||
|
In the C<PolyLib> format output,
|
||
|
the coefficients of the existentially quantified variables
|
||
|
appear between those of the set variables and those
|
||
|
of the parameters.
|
||
|
The function C<isl_printer_indent> increases the indentation
|
||
|
by the specified amount (which may be negative).
|
||
|
The YAML style may be either C<ISL_YAML_STYLE_BLOCK> or
|
||
|
C<ISL_YAML_STYLE_FLOW> and when we are printing something
|
||
|
in YAML format.
|
||
|
|
||
|
To actually print something, use
|
||
|
|
||
|
#include <isl/printer.h>
|
||
|
__isl_give isl_printer *isl_printer_print_double(
|
||
|
__isl_take isl_printer *p, double d);
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__isl_give isl_printer *isl_printer_print_val(
|
||
|
__isl_take isl_printer *p, __isl_keep isl_val *v);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_set.h>
|
||
|
__isl_give isl_printer *isl_printer_print_union_set(
|
||
|
__isl_take isl_printer *p,
|
||
|
__isl_keep isl_union_set *uset);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__isl_give isl_printer *isl_printer_print_union_map(
|
||
|
__isl_take isl_printer *p,
|
||
|
__isl_keep isl_union_map *umap);
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__isl_give isl_printer *isl_printer_print_multi_val(
|
||
|
__isl_take isl_printer *p,
|
||
|
__isl_keep isl_multi_val *mv);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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<isl_printer_print_qpolynomial>,
|
||
|
C<isl_printer_print_pw_qpolynomial> and
|
||
|
C<isl_printer_print_pw_qpolynomial_fold>,
|
||
|
the output format of the printer
|
||
|
needs to be set to either C<ISL_FORMAT_ISL> or C<ISL_FORMAT_C>.
|
||
|
For C<isl_printer_print_union_pw_qpolynomial> and
|
||
|
C<isl_printer_print_union_pw_qpolynomial_fold>, only C<ISL_FORMAT_ISL>
|
||
|
is supported.
|
||
|
In case of printing in C<ISL_FORMAT_C>, the user may want
|
||
|
to set the names of all dimensions first.
|
||
|
|
||
|
C<isl> also provides limited support for printing YAML documents,
|
||
|
just enough for the internal use for printing such documents.
|
||
|
|
||
|
#include <isl/printer.h>
|
||
|
__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<isl_printer_yaml_start_mapping> or C<isl_printer_yaml_start_sequence>.
|
||
|
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<isl_printer_yaml_next> 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<isl_printer_yaml_start_mapping> or C<isl_printer_yaml_start_sequence>.
|
||
|
Each call to these functions needs to have a corresponding call to
|
||
|
C<isl_printer_yaml_end_mapping> or C<isl_printer_yaml_end_sequence>.
|
||
|
|
||
|
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/printer.h>
|
||
|
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<isl_printer_set_note> associates the given note to the given
|
||
|
identifier in the printer.
|
||
|
C<isl_printer_get_note> retrieves a note associated to an
|
||
|
identifier, while
|
||
|
C<isl_printer_has_note> checks if there is such a note.
|
||
|
C<isl_printer_get_note> 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/id.h>
|
||
|
__isl_give char *isl_id_to_str(
|
||
|
__isl_keep isl_id *id);
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__isl_give char *isl_space_to_str(
|
||
|
__isl_keep isl_space *space);
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__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/set.h>
|
||
|
__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/union_set.h>
|
||
|
__isl_give char *isl_union_set_to_str(
|
||
|
__isl_keep isl_union_set *uset);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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/union_map.h>
|
||
|
__isl_give char *isl_union_map_to_str(
|
||
|
__isl_keep isl_union_map *umap);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/point.h>
|
||
|
__isl_give char *isl_point_to_str(
|
||
|
__isl_keep isl_point *pnt);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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.
|
||
|
|
||
|
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);
|
||
|
isl_bool isl_union_set_is_empty(
|
||
|
__isl_keep isl_union_set *uset);
|
||
|
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);
|
||
|
isl_bool isl_union_map_is_empty(
|
||
|
__isl_keep isl_union_map *umap);
|
||
|
|
||
|
=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/set.h>
|
||
|
isl_bool isl_set_is_singleton(__isl_keep isl_set *set);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
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/union_map.h>
|
||
|
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/map.h>
|
||
|
isl_bool isl_map_is_identity(
|
||
|
__isl_keep isl_map *map);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
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_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.
|
||
|
|
||
|
=item * Stride
|
||
|
|
||
|
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>.
|
||
|
|
||
|
=item * Dependence
|
||
|
|
||
|
To check whether the description of a set, relation or function depends
|
||
|
on one or more given dimensions,
|
||
|
the following functions can be used.
|
||
|
|
||
|
#include <isl/constraint.h>
|
||
|
isl_bool isl_constraint_involves_dims(
|
||
|
__isl_keep isl_constraint *constraint,
|
||
|
enum isl_dim_type type, unsigned first, unsigned n);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
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/map.h>
|
||
|
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/union_map.h>
|
||
|
isl_bool isl_union_map_involves_dims(
|
||
|
__isl_keep isl_union_map *umap,
|
||
|
enum isl_dim_type type, unsigned first, unsigned n);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
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_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_multi_pw_aff_involves_dims(
|
||
|
__isl_keep isl_multi_pw_aff *mpa,
|
||
|
enum isl_dim_type type, unsigned first, unsigned n);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
isl_bool isl_qpolynomial_involves_dims(
|
||
|
__isl_keep isl_qpolynomial *qp,
|
||
|
enum isl_dim_type type, unsigned first, unsigned n);
|
||
|
|
||
|
Similarly, the following functions can be used to check whether
|
||
|
a given dimension is involved in any lower or upper bound.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
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<set>.
|
||
|
To check if they have a bound for all of the basic sets in C<set>,
|
||
|
use the following functions instead.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
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/space.h>
|
||
|
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/set.h>
|
||
|
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/map.h>
|
||
|
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/val.h>
|
||
|
isl_bool isl_multi_val_range_is_wrapping(
|
||
|
__isl_keep isl_multi_val *mv);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
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<isl_space_is_wrapping> should
|
||
|
be the space of a set, while that of
|
||
|
C<isl_space_domain_is_wrapping> and
|
||
|
C<isl_space_range_is_wrapping> should be the space of a relation.
|
||
|
The input to C<isl_space_is_product> 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/space.h>
|
||
|
isl_bool isl_space_can_curry(
|
||
|
__isl_keep isl_space *space);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
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/space.h>
|
||
|
__isl_give isl_space *isl_space_uncurry(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
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/space.h>
|
||
|
isl_bool isl_space_can_range_curry(
|
||
|
__isl_keep isl_space *space);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
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/aff.h>
|
||
|
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/val.h>
|
||
|
isl_bool isl_multi_val_involves_nan(
|
||
|
__isl_keep isl_multi_val *mv);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
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/polynomial.h>
|
||
|
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/aff.h>
|
||
|
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<plain> 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/set.h>
|
||
|
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/map.h>
|
||
|
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/union_set.h>
|
||
|
isl_bool isl_union_set_is_equal(
|
||
|
__isl_keep isl_union_set *uset1,
|
||
|
__isl_keep isl_union_set *uset2);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
isl_bool isl_union_map_is_equal(
|
||
|
__isl_keep isl_union_map *umap1,
|
||
|
__isl_keep isl_union_map *umap2);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
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/polynomial.h>
|
||
|
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/set.h>
|
||
|
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/map.h>
|
||
|
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/union_set.h>
|
||
|
isl_bool isl_union_set_is_disjoint(
|
||
|
__isl_keep isl_union_set *uset1,
|
||
|
__isl_keep isl_union_set *uset2);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
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 <isl/constraint.h>
|
||
|
int isl_constraint_plain_cmp(
|
||
|
__isl_keep isl_constraint *c1,
|
||
|
__isl_keep isl_constraint *c2);
|
||
|
|
||
|
This function is useful for sorting C<isl_constraint>s.
|
||
|
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<isl>.
|
||
|
|
||
|
#include <isl/constraint.h>
|
||
|
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<partial> order.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
int isl_set_plain_cmp(__isl_keep isl_set *set1,
|
||
|
__isl_keep isl_set *set2);
|
||
|
|
||
|
This function is useful for sorting C<isl_set>s.
|
||
|
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<isl>.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
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<isl_multi_aff_plain_cmp> and
|
||
|
C<isl_pw_aff_plain_cmp> can be used to sort C<isl_multi_aff>s and
|
||
|
C<isl_pw_aff>s. 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/space.h>
|
||
|
__isl_give isl_space *isl_space_reverse(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__isl_give isl_union_map *isl_union_map_reverse(
|
||
|
__isl_take isl_union_map *umap);
|
||
|
|
||
|
=item * Projection
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__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);
|
||
|
|
||
|
#include <isl/local_space.h>
|
||
|
__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/set.h>
|
||
|
__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(__isl_take isl_set *set,
|
||
|
enum isl_dim_type type, unsigned first, unsigned n);
|
||
|
__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<isl_set_project_onto_map> returns a relation
|
||
|
that projects the input set onto the given set dimensions.
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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(__isl_take isl_map *map,
|
||
|
enum isl_dim_type type, unsigned first, unsigned n);
|
||
|
__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/union_set.h>
|
||
|
__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_set *isl_union_set_params(
|
||
|
__isl_take isl_union_set *uset);
|
||
|
|
||
|
The function C<isl_union_set_project_out> can only project out
|
||
|
parameters.
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__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_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<isl_union_map_project_out> can only project out
|
||
|
parameters.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_aff *isl_aff_project_domain_on_params(
|
||
|
__isl_take isl_aff *aff);
|
||
|
__isl_give isl_pw_aff *
|
||
|
isl_pw_aff_project_domain_on_params(
|
||
|
__isl_take isl_pw_aff *pa);
|
||
|
__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);
|
||
|
|
||
|
The function C<isl_multi_union_pw_aff_domain> requires its
|
||
|
input to have at least one set dimension.
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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/space.h>
|
||
|
__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/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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<isl_set_wrapped_domain_map> 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 zero-dimensional space or (basic) set can be constructed
|
||
|
on a given parameter domain using the following functions.
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__isl_give isl_space *isl_space_set_from_params(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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
|
||
|
|
||
|
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.
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__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/local_space.h>
|
||
|
__isl_give isl_local_space *isl_local_space_from_domain(
|
||
|
__isl_take isl_local_space *ls);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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/val.h>
|
||
|
__isl_give isl_multi_val *isl_multi_val_from_range(
|
||
|
__isl_take isl_multi_val *mv);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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);
|
||
|
|
||
|
Intersect the set, relation or function domain
|
||
|
with the hyperplane where the given
|
||
|
dimension has the fixed given value.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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);
|
||
|
|
||
|
Intersect the set or relation with the half-space where the given
|
||
|
dimension has a value bounded by the fixed given integer value.
|
||
|
|
||
|
__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.
|
||
|
|
||
|
=item * Locus
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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<isl_aff_neg_basic_set> returns a basic set
|
||
|
containing those elements in the domain space
|
||
|
of C<aff> where C<aff> is negative.
|
||
|
The function C<isl_pw_aff_nonneg_set> returns a set
|
||
|
containing those elements in the domain
|
||
|
of C<pwaff> where C<pwaff> is non-negative.
|
||
|
The function C<isl_multi_union_pw_aff_zero_union_set>
|
||
|
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/aff.h>
|
||
|
__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<isl_set> or C<isl_map>, provided the C<isl_set> is a singleton
|
||
|
and the C<isl_map> is single-valued.
|
||
|
In case of a conversion from an C<isl_union_map>
|
||
|
to an C<isl_union_pw_multi_aff>, these properties need to hold
|
||
|
in each domain space.
|
||
|
A conversion to a C<isl_multi_union_pw_aff> additionally
|
||
|
requires that the input is non-empty and involves only a single
|
||
|
range space.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(
|
||
|
__isl_take isl_set *set);
|
||
|
__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_pw_multi_aff_from_union_map(
|
||
|
__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);
|
||
|
|
||
|
=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 * 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/set.h>
|
||
|
__isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map);
|
||
|
|
||
|
#include <isl/union_set.h>
|
||
|
__isl_give isl_union_set *isl_union_set_coalesce(
|
||
|
__isl_take isl_union_set *uset);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__isl_give isl_union_map *isl_union_map_coalesce(
|
||
|
__isl_take isl_union_map *umap);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_pw_aff *isl_pw_aff_coalesce(
|
||
|
__isl_take isl_pw_aff *pwqp);
|
||
|
__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 *aff);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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);
|
||
|
|
||
|
=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/set.h>
|
||
|
__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/union_set.h>
|
||
|
__isl_give isl_union_set *
|
||
|
isl_union_set_remove_redundancies(
|
||
|
__isl_take isl_union_set *uset);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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<isl_set_unshifted_simple_hull>, only the original
|
||
|
constraints are used, without any translation.
|
||
|
In case of C<isl_set_plain_unshifted_simple_hull> and
|
||
|
C<isl_map_plain_unshifted_simple_hull>, the result is described
|
||
|
by original constraints that are obviously satisfied
|
||
|
by the entire input set or relation.
|
||
|
In case of C<isl_set_unshifted_simple_hull_from_set_list> and
|
||
|
C<isl_map_unshifted_simple_hull_from_map_list>, 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 * Other approximations
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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/map.h>
|
||
|
__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/polynomial.h>
|
||
|
__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<sign> is positive,
|
||
|
the polynomial will be an overapproximation. If C<sign> is negative,
|
||
|
it will be an underapproximation. If C<sign> 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/ilp.h>
|
||
|
__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 *set,
|
||
|
__isl_keep isl_multi_union_pw_aff *obj);
|
||
|
|
||
|
Compute the minimum or maximum of the integer affine expression C<obj>
|
||
|
over the points in C<set>, returning the result in C<opt>.
|
||
|
The result is C<NULL> in case of an error, the optimal value in case
|
||
|
there is one, negative infinity or infinity if the problem is unbounded and
|
||
|
NaN if the problem is empty.
|
||
|
|
||
|
=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);
|
||
|
|
||
|
Compute the minimum or maximum of the given set or output dimension
|
||
|
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/set.h>
|
||
|
__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<map>, where C<exp> is assumed to be non-zero.
|
||
|
If the exponent C<exp> is negative, then the -C<exp> th power of the inverse
|
||
|
of C<map> is computed.
|
||
|
|
||
|
__isl_give isl_map *isl_map_power(__isl_take isl_map *map,
|
||
|
int *exact);
|
||
|
__isl_give isl_union_map *isl_union_map_power(
|
||
|
__isl_take isl_union_map *umap, int *exact);
|
||
|
|
||
|
Compute a parametric representation for all positive powers I<k> of C<map>.
|
||
|
The result maps I<k> to a nested relation corresponding to the
|
||
|
I<k>th power of C<map>.
|
||
|
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, int *exact);
|
||
|
__isl_give isl_union_map *isl_union_map_transitive_closure(
|
||
|
__isl_take isl_union_map *umap, int *exact);
|
||
|
|
||
|
Compute the transitive closure of C<map>.
|
||
|
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, int *exact);
|
||
|
|
||
|
Compute a relation that maps each element in the range of C<map>
|
||
|
to the lengths of all paths composed of edges in C<map> 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<maximal> path length, the resulting relation
|
||
|
should be postprocessed by C<isl_map_lexmax>.
|
||
|
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<isl_map_lexmax> 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/space.h>
|
||
|
__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/local_space.h>
|
||
|
__isl_give isl_local_space *isl_local_space_wrap(
|
||
|
__isl_take isl_local_space *ls);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_set.h>
|
||
|
__isl_give isl_union_map *isl_union_set_unwrap(
|
||
|
__isl_take isl_union_set *uset);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__isl_give isl_union_set *isl_union_map_wrap(
|
||
|
__isl_take isl_union_map *umap);
|
||
|
|
||
|
The input to C<isl_space_unwrap> should
|
||
|
be the space of a set, while that of
|
||
|
C<isl_space_wrap> should be the space of a relation.
|
||
|
Conversely, the output of C<isl_space_unwrap> is the space
|
||
|
of a relation, while that of C<isl_space_wrap> 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/local_space.h>
|
||
|
__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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/val.h>
|
||
|
__isl_give isl_multi_val *isl_multi_val_flatten_range(
|
||
|
__isl_take isl_multi_val *mv);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/map.h>
|
||
|
__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/set.h>
|
||
|
__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<isl_basic_set_lift>,
|
||
|
can be constructed using the following function.
|
||
|
|
||
|
#include <isl/local_space.h>
|
||
|
__isl_give isl_basic_map *isl_local_space_lifting(
|
||
|
__isl_take isl_local_space *ls);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__isl_give isl_multi_aff *isl_multi_aff_lift(
|
||
|
__isl_take isl_multi_aff *maff,
|
||
|
__isl_give isl_local_space **ls);
|
||
|
|
||
|
If the C<ls> argument of C<isl_multi_aff_lift> is not C<NULL>,
|
||
|
then it is assigned the local space that lies at the basis of
|
||
|
the lifting applied.
|
||
|
|
||
|
=item * Internal Product
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__isl_give isl_space *isl_space_zip(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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/space.h>
|
||
|
__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/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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<curry> 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<uncurry> functions perform the inverse operation.
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__isl_give isl_space *isl_space_range_curry(
|
||
|
__isl_take isl_space *space);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__isl_give isl_map *isl_map_range_curry(
|
||
|
__isl_take isl_map *map);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__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<model>.
|
||
|
This may involve the introduction of extra parameters.
|
||
|
All parameters need to be named.
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__isl_give isl_space *isl_space_align_params(
|
||
|
__isl_take isl_space *space1,
|
||
|
__isl_take isl_space *space2)
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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/map.h>
|
||
|
__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/val.h>
|
||
|
__isl_give isl_multi_val *isl_multi_val_align_params(
|
||
|
__isl_take isl_multi_val *mv,
|
||
|
__isl_take isl_space *model);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__isl_give isl_qpolynomial *isl_qpolynomial_align_params(
|
||
|
__isl_take isl_qpolynomial *qp,
|
||
|
__isl_take isl_space *model);
|
||
|
|
||
|
=item * Unary Arithmetic Operations
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__isl_give isl_set *isl_set_neg(
|
||
|
__isl_take isl_set *set);
|
||
|
#include <isl/map.h>
|
||
|
__isl_give isl_map *isl_map_neg(
|
||
|
__isl_take isl_map *map);
|
||
|
|
||
|
C<isl_set_neg> constructs a set containing the opposites of
|
||
|
the elements in its argument.
|
||
|
The domain of the result of C<isl_map_neg> 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/val.h>
|
||
|
__isl_give isl_multi_val *isl_multi_val_neg(
|
||
|
__isl_take isl_multi_val *mv);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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/polynomial.h>
|
||
|
__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);
|
||
|
|
||
|
=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<isl_set_align_params> and C<isl_map_align_params>
|
||
|
are not sufficient.
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__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/local_space.h>
|
||
|
__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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/val.h>
|
||
|
__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/aff.h>
|
||
|
__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/polynomial.h>
|
||
|
__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<isl_ctx>, they currently also need to have
|
||
|
the same (number of) parameters.
|
||
|
|
||
|
=head3 Basic Operations
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item * Intersection
|
||
|
|
||
|
#include <isl/local_space.h>
|
||
|
__isl_give isl_local_space *isl_local_space_intersect(
|
||
|
__isl_take isl_local_space *ls1,
|
||
|
__isl_take isl_local_space *ls2);
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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_range(
|
||
|
__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);
|
||
|
|
||
|
#include <isl/union_set.h>
|
||
|
__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/union_map.h>
|
||
|
__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(
|
||
|
__isl_take isl_union_map *umap,
|
||
|
__isl_take isl_union_set *uset);
|
||
|
__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_range_factor_range(
|
||
|
__isl_take isl_union_map *umap,
|
||
|
__isl_take isl_union_map *factor);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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(
|
||
|
__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(
|
||
|
__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_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_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_multi_union_pw_aff_intersect_range(
|
||
|
__isl_take isl_multi_union_pw_aff *mupa,
|
||
|
__isl_take isl_set *set);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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(
|
||
|
__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(
|
||
|
__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<isl_basic_set_list_intersect> needs to have
|
||
|
at least one element and all elements need to live in the same space.
|
||
|
The function C<isl_multi_union_pw_aff_intersect_range>
|
||
|
restricts the input function to those shared domain elements
|
||
|
that map to the specified range.
|
||
|
|
||
|
=item * Union
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_set.h>
|
||
|
__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/union_map.h>
|
||
|
__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<isl_set_list_union> needs to have
|
||
|
at least one element and all elements need to live in the same space.
|
||
|
|
||
|
=item * Set difference
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__isl_give isl_set *isl_set_subtract(
|
||
|
__isl_take isl_set *set1,
|
||
|
__isl_take isl_set *set2);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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/union_set.h>
|
||
|
__isl_give isl_union_set *isl_union_set_subtract(
|
||
|
__isl_take isl_union_set *uset1,
|
||
|
__isl_take isl_union_set *uset2);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__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/aff.h>
|
||
|
__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(
|
||
|
__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(
|
||
|
__isl_take isl_union_pw_multi_aff *upma,
|
||
|
__isl_take isl_set *set);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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(
|
||
|
__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(
|
||
|
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||
|
__isl_take isl_union_set *uset);
|
||
|
|
||
|
=item * Application
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__isl_give isl_space *isl_space_join(
|
||
|
__isl_take isl_space *left,
|
||
|
__isl_take isl_space *right);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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);
|
||
|
__isl_give isl_union_set *isl_union_set_apply(
|
||
|
__isl_take isl_union_set *uset,
|
||
|
__isl_take isl_union_map *umap);
|
||
|
__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/union_map.h>
|
||
|
__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/aff.h>
|
||
|
__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<isl_multi_union_pw_aff_apply_aff> is defined
|
||
|
over the shared domain of the elements of the input. The dimension is
|
||
|
required to be greater than zero.
|
||
|
The C<isl_multi_union_pw_aff> argument of
|
||
|
C<isl_multi_union_pw_aff_apply_multi_aff> is allowed to be zero-dimensional,
|
||
|
but only if the range of the C<isl_multi_aff> argument
|
||
|
is also zero-dimensional.
|
||
|
Similarly for C<isl_multi_union_pw_aff_apply_pw_multi_aff>.
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__isl_give isl_pw_qpolynomial_fold *
|
||
|
isl_set_apply_pw_qpolynomial_fold(
|
||
|
__isl_take isl_set *set,
|
||
|
__isl_take isl_pw_qpolynomial_fold *pwf,
|
||
|
int *tight);
|
||
|
__isl_give isl_pw_qpolynomial_fold *
|
||
|
isl_map_apply_pw_qpolynomial_fold(
|
||
|
__isl_take isl_map *map,
|
||
|
__isl_take isl_pw_qpolynomial_fold *pwf,
|
||
|
int *tight);
|
||
|
__isl_give isl_union_pw_qpolynomial_fold *
|
||
|
isl_union_set_apply_union_pw_qpolynomial_fold(
|
||
|
__isl_take isl_union_set *uset,
|
||
|
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||
|
int *tight);
|
||
|
__isl_give isl_union_pw_qpolynomial_fold *
|
||
|
isl_union_map_apply_union_pw_qpolynomial_fold(
|
||
|
__isl_take isl_union_map *umap,
|
||
|
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||
|
int *tight);
|
||
|
|
||
|
The functions taking a map
|
||
|
compose the given map with the given piecewise quasipolynomial reduction.
|
||
|
That is, compute a bound (of the same type as C<pwf> or C<upwf> itself)
|
||
|
over all elements in the intersection of the range of the map
|
||
|
and the domain of the piecewise quasipolynomial reduction
|
||
|
as a function of an element in the domain of the map.
|
||
|
The functions taking a set compute a bound over all elements in the
|
||
|
intersection of the set and the domain of the
|
||
|
piecewise quasipolynomial reduction.
|
||
|
|
||
|
=item * Preimage
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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/union_set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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);
|
||
|
|
||
|
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.
|
||
|
|
||
|
=item * Pullback
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/aff.h>
|
||
|
__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<isl_aff_ge_basic_set> returns a basic set
|
||
|
containing those elements in the shared space
|
||
|
of C<aff1> and C<aff2> where C<aff1> is greater than or equal to C<aff2>.
|
||
|
The function C<isl_pw_aff_ge_set> returns a set
|
||
|
containing those elements in the shared domain
|
||
|
of C<pwaff1> and C<pwaff2> where C<pwaff1> is
|
||
|
greater than or equal to C<pwaff2>.
|
||
|
The function C<isl_multi_aff_lex_le_set> returns a set
|
||
|
containing those elements in the shared domain space
|
||
|
where C<ma1> is lexicographically smaller than or
|
||
|
equal to C<ma2>.
|
||
|
The functions operating on C<isl_pw_aff_list> apply the corresponding
|
||
|
C<isl_pw_aff> function to each pair of elements in the two lists.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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_lt_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_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_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/union_map.h>
|
||
|
__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_gt_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 function value.
|
||
|
|
||
|
=item * Cartesian Product
|
||
|
|
||
|
#include <isl/space.h>
|
||
|
__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<isl_space_product>, C<isl_space_domain_product>
|
||
|
and C<isl_space_range_product> 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<isl_space_product> 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/set.h>
|
||
|
__isl_give isl_set *isl_set_product(
|
||
|
__isl_take isl_set *set1,
|
||
|
__isl_take isl_set *set2);
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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/union_set.h>
|
||
|
__isl_give isl_union_set *isl_union_set_product(
|
||
|
__isl_take isl_union_set *uset1,
|
||
|
__isl_take isl_union_set *uset2);
|
||
|
|
||
|
#include <isl/union_map.h>
|
||
|
__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/val.h>
|
||
|
__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/aff.h>
|
||
|
__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_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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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/val.h>
|
||
|
__isl_give isl_multi_val *isl_multi_val_flat_range_product(
|
||
|
__isl_take isl_multi_val *mv1,
|
||
|
__isl_take isl_multi_aff *mv2);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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/space.h>
|
||
|
__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<isl_space_range_factor_domain> and
|
||
|
C<isl_space_range_factor_range> extract the two arguments from
|
||
|
the result of a call to C<isl_space_range_product>.
|
||
|
|
||
|
The arguments of a call to a product can be extracted
|
||
|
from the result using the following functions.
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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/union_map.h>
|
||
|
__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/val.h>
|
||
|
__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/aff.h>
|
||
|
__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_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<isl_multi_val_factor_range>,
|
||
|
C<isl_multi_aff_factor_range>,
|
||
|
C<isl_multi_pw_aff_factor_range> and
|
||
|
C<isl_multi_union_pw_aff_factor_range>
|
||
|
take functions that live in a set space.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__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/aff.h>
|
||
|
__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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/union_set.h>
|
||
|
__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/union_map.h>
|
||
|
__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/aff.h>
|
||
|
__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 *aff,
|
||
|
__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 *aff,
|
||
|
__isl_take isl_union_set *context);
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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/set.h>
|
||
|
__isl_give isl_set *isl_set_sum(
|
||
|
__isl_take isl_set *set1,
|
||
|
__isl_take isl_set *set2);
|
||
|
#include <isl/map.h>
|
||
|
__isl_give isl_map *isl_map_sum(
|
||
|
__isl_take isl_map *map1,
|
||
|
__isl_take isl_map *map2);
|
||
|
|
||
|
C<isl_set_sum> computes the Minkowski sum of its two arguments,
|
||
|
i.e., the set containing the sums of pairs of elements from
|
||
|
C<set1> and C<set2>.
|
||
|
The domain of the result of C<isl_map_sum> 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/val.h>
|
||
|
__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);
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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_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_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<isl_aff_sub> subtracts the second argument from the first.
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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/aff.h>
|
||
|
__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_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<isl_pw_aff_union_max> computes a piecewise quasi-affine
|
||
|
expression with a domain that is the union of those of C<pwaff1> and
|
||
|
C<pwaff2> and such that on each cell, the quasi-affine expression is
|
||
|
the maximum of those of C<pwaff1> and C<pwaff2>. If only one of
|
||
|
C<pwaff1> or C<pwaff2> is defined on a given cell, then the
|
||
|
associated expression is the defined one.
|
||
|
This in contrast to the C<isl_pw_aff_max> function, which is
|
||
|
only defined on the shared definition domain of the arguments.
|
||
|
|
||
|
#include <isl/val.h>
|
||
|
__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/aff.h>
|
||
|
__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_multi_aff *
|
||
|
__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_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/polynomial.h>
|
||
|
__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/val.h>
|
||
|
__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/aff.h>
|
||
|
__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_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<isl_multi_aff_scale_multi_val> scales the elements of C<ma>
|
||
|
by the corresponding elements of C<mv>.
|
||
|
|
||
|
#include <isl/aff.h>
|
||
|
__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<isl_pw_aff_tdiv_q> computes the quotient of an integer division with
|
||
|
rounding towards zero. C<isl_pw_aff_tdiv_r> computes the corresponding
|
||
|
remainder.
|
||
|
|
||
|
#include <isl/polynomial.h>
|
||
|
__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<set> (or C<bset>) and a zero-dimensional domain C<dom>,
|
||
|
the following functions
|
||
|
compute a set that contains the lexicographic minimum or maximum
|
||
|
of the elements in C<set> (or C<bset>) for those values of the parameters
|
||
|
that satisfy C<dom>.
|
||
|
If C<empty> is not C<NULL>, then C<*empty> is assigned a set
|
||
|
that contains the parameter values in C<dom> for which C<set> (or C<bset>)
|
||
|
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<dom>.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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<set> (or C<bset>), the following functions simply
|
||
|
return a set containing the lexicographic minimum or maximum
|
||
|
of the elements in C<set> (or C<bset>).
|
||
|
In case of union sets, the optimum is computed per space.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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<map> (or C<bmap>) and a domain C<dom>,
|
||
|
the following functions
|
||
|
compute a relation that maps each element of C<dom>
|
||
|
to the single lexicographic minimum or maximum
|
||
|
of the elements that are associated to that same
|
||
|
element in C<map> (or C<bmap>).
|
||
|
If C<empty> is not C<NULL>, then C<*empty> is assigned a set
|
||
|
that contains the elements in C<dom> that do not map
|
||
|
to any elements in C<map> (or C<bmap>).
|
||
|
In other words, the union of the domain of the result and of C<*empty>
|
||
|
is equal to C<dom>.
|
||
|
|
||
|
#include <isl/map.h>
|
||
|
__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<map> (or C<bmap>), the following functions simply
|
||
|
return a map mapping each element in the domain of
|
||
|
C<map> (or C<bmap>) 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/map.h>
|
||
|
__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/set.h>
|
||
|
__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/map.h>
|
||
|
__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/aff.h>
|
||
|
__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/options.h>
|
||
|
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/aff.h>
|
||
|
__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<isl_pw_aff_cond> performs a conditional operator
|
||
|
and returns an expression that is equal to C<pwaff_true>
|
||
|
for elements where C<cond> is non-zero and equal to C<pwaff_false> for elements
|
||
|
where C<cond> is zero.
|
||
|
|
||
|
=head2 Lists
|
||
|
|
||
|
Lists are defined over several element types, including
|
||
|
C<isl_val>, C<isl_id>, C<isl_aff>, C<isl_pw_aff>, C<isl_union_pw_aff>,
|
||
|
C<isl_union_pw_multi_aff>, C<isl_constraint>,
|
||
|
C<isl_basic_set>, C<isl_set>, C<isl_basic_map>, C<isl_map>, C<isl_union_set>,
|
||
|
C<isl_union_map>, C<isl_ast_expr> and C<isl_ast_node>.
|
||
|
Here we take lists of C<isl_set>s as an example.
|
||
|
Lists can be created, copied, modified and freed using the following functions.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__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_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<isl_set_list_alloc> creates an empty list with an initial capacity
|
||
|
for C<n> elements. C<isl_set_list_insert> and C<isl_set_list_add>
|
||
|
add elements to a list, increasing its capacity as needed.
|
||
|
C<isl_set_list_from_set> creates a list with a single element.
|
||
|
|
||
|
Lists can be inspected using the following functions.
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
int isl_set_list_n_set(__isl_keep isl_set_list *list);
|
||
|
__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_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 *el, void *user),
|
||
|
void *fn_user);
|
||
|
|
||
|
The function C<isl_set_list_foreach_scc> calls C<fn> on each of the
|
||
|
strongly connected components of the graph with as vertices the elements
|
||
|
of C<list> and a directed edge from vertex C<b> to vertex C<a>
|
||
|
iff C<follows(a, b)> returns C<isl_bool_true>. The callbacks C<follows> and
|
||
|
C<fn> should return C<isl_bool_error> or C<isl_stat_error> on error.
|
||
|
|
||
|
Lists can be printed using
|
||
|
|
||
|
#include <isl/set.h>
|
||
|
__isl_give isl_printer *isl_printer_print_set_list(
|
||
|
__isl_take isl_printer *p,
|
||
|
__isl_keep isl_set_list *list);
|
||
|
|
||
|
=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<isl_map>, C<isl_basic_set>),
|
||
|
(C<isl_id>, C<isl_ast_expr>),
|
||
|
(C<isl_id>, C<isl_id>) and
|
||
|
(C<isl_id>, C<isl_pw_aff>).
|
||
|
Here, we take associative arrays that map C<isl_id>s to C<isl_ast_expr>s
|
||
|
as an example.
|
||
|
|
||
|
Associative arrays can be created, copied and freed using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/id_to_ast_expr.h>
|
||
|
__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<min_size> argument to C<isl_id_to_ast_expr_alloc> 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/id_to_ast_expr.h>
|
||
|
__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);
|
||
|
|
||
|
The function C<isl_id_to_ast_expr_try_get> returns a structure
|
||
|
containing two elements, C<valid> and C<value>.
|
||
|
If there is a value associated to the key, then C<valid>
|
||
|
is set to C<isl_bool_true> and C<value> contains a copy of
|
||
|
the associated value. Otherwise C<value> is C<NULL> and
|
||
|
C<valid> may be C<isl_bool_error> or C<isl_bool_false> depending
|
||
|
on whether some error has occurred or there simply is no associated value.
|
||
|
The function C<isl_id_to_ast_expr_has> returns the C<valid> field
|
||
|
in the structure and
|
||
|
the function C<isl_id_to_ast_expr_get> returns the C<value> field.
|
||
|
|
||
|
Associative arrays can be modified using the following functions.
|
||
|
|
||
|
#include <isl/id_to_ast_expr.h>
|
||
|
__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 printed using the following function.
|
||
|
|
||
|
#include <isl/id_to_ast_expr.h>
|
||
|
__isl_give isl_printer *isl_printer_print_id_to_ast_expr(
|
||
|
__isl_take isl_printer *p,
|
||
|
__isl_keep isl_id_to_ast_expr *id2expr);
|
||
|
|
||
|
=head2 Vectors
|
||
|
|
||
|
Vectors can be created, copied and freed using the following functions.
|
||
|
|
||
|
#include <isl/vec.h>
|
||
|
__isl_give isl_vec *isl_vec_alloc(isl_ctx *ctx,
|
||
|
unsigned size);
|
||
|
__isl_give isl_vec *isl_vec_copy(__isl_keep isl_vec *vec);
|
||
|
__isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec);
|
||
|
|
||
|
Note that the elements of a newly created vector may have arbitrary values.
|
||
|
The elements can be changed and inspected using the following functions.
|
||
|
|
||
|
int 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<isl_vec_get_element> 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/mat.h>
|
||
|
__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.
|
||
|
|
||
|
int isl_mat_rows(__isl_keep isl_mat *mat);
|
||
|
int 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);
|
||
|
|
||
|
C<isl_mat_get_element> will return a negative value if anything went wrong.
|
||
|
In that case, the value of C<*v> is undefined.
|
||
|
|
||
|
The following function 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);
|
||
|
|
||
|
=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, int *tight);
|
||
|
|
||
|
__isl_give isl_union_pw_qpolynomial_fold *
|
||
|
isl_union_pw_qpolynomial_bound(
|
||
|
__isl_take isl_union_pw_qpolynomial *upwqp,
|
||
|
enum isl_fold type, int *tight);
|
||
|
|
||
|
The C<type> argument may be either C<isl_fold_min> or C<isl_fold_max>.
|
||
|
If C<tight> is not C<NULL>, 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<pwqp> 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<pwqp> 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<barvinok>
|
||
|
library.
|
||
|
|
||
|
#include <isl/vertices.h>
|
||
|
__isl_give isl_vertices *isl_basic_set_compute_vertices(
|
||
|
__isl_keep isl_basic_set *bset);
|
||
|
|
||
|
The function C<isl_basic_set_compute_vertices> performs the
|
||
|
actual computation of the parametric vertices and the chamber
|
||
|
decomposition and stores the result in an C<isl_vertices> 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<isl_vertices> object are
|
||
|
the following.
|
||
|
|
||
|
int 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.
|
||
|
|
||
|
int 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);
|
||
|
void isl_vertex_free(__isl_take isl_vertex *vertex);
|
||
|
|
||
|
C<isl_vertex_get_expr> returns a multiple quasi-affine expression
|
||
|
describing the vertex in terms of the parameters,
|
||
|
while C<isl_vertex_get_domain> 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);
|
||
|
void isl_cell_free(__isl_take isl_cell *cell);
|
||
|
|
||
|
=head1 Polyhedral Compilation Library
|
||
|
|
||
|
This section collects functionality in C<isl> 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<isl_schedule_node_domain>
|
||
|
(or C<isl_schedule_node_extension>)
|
||
|
and it describes the (extra) domain elements to which the schedule applies.
|
||
|
The other types of nodes are as follows.
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item C<isl_schedule_node_band>
|
||
|
|
||
|
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<isl_schedule_node_expansion>
|
||
|
|
||
|
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<isl_schedule_node_filter>
|
||
|
|
||
|
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<isl_schedule_node_leaf>
|
||
|
|
||
|
A leaf of the schedule tree. Leaf nodes do not impose any ordering.
|
||
|
|
||
|
=item C<isl_schedule_node_mark>
|
||
|
|
||
|
A mark node can be used to attach any kind of information to a subtree
|
||
|
of the schedule tree.
|
||
|
|
||
|
=item C<isl_schedule_node_sequence>
|
||
|
|
||
|
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<isl_schedule_node_set>
|
||
|
|
||
|
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<isl_schedule_node_context>
|
||
|
|
||
|
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<isl_schedule_node_extension>
|
||
|
|
||
|
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.
|
||
|
|
||
|
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<isl_schedule_node_graft_before> or C<isl_schedule_node_graft_after>.
|
||
|
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<isl_schedule_node_guard>
|
||
|
|
||
|
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.
|
||
|
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<isl_schedule_node_context> 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<isl_schedule> 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/schedule.h>
|
||
|
__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<isl_schedule_constraints_compute_schedule> described
|
||
|
in L</"Scheduling"> can also be used to construct schedules.
|
||
|
|
||
|
C<isl_schedule> objects may be copied and freed using the following functions.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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<isl_schedule> objects
|
||
|
are obviously the same.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
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/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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<isl_schedule_node_sequence>
|
||
|
or an C<isl_schedule_node_set> node,
|
||
|
can be created using the following functions.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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<expansion>
|
||
|
in the leaves of C<schedule>, where C<contraction> describes how
|
||
|
the domain elements of C<expansion> map to the domain elements
|
||
|
at the original leaves of C<schedule>.
|
||
|
The resulting schedule will contain expansion nodes, unless
|
||
|
C<contraction> is an identity function.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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<isl_union_map> representation of the schedule can be obtained
|
||
|
from an C<isl_schedule> using the following function.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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/schedule.h>
|
||
|
__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<isl_schedule_to_str> prints the schedule in flow format.
|
||
|
|
||
|
The schedule tree can be traversed through the use of
|
||
|
C<isl_schedule_node> objects that point to a particular
|
||
|
position in the schedule tree. Whenever a C<isl_schedule_node>
|
||
|
is use to modify a node in the schedule tree, the original schedule
|
||
|
tree is left untouched and the modifications are performed to a copy
|
||
|
of the tree. The returned C<isl_schedule_node> then points to
|
||
|
this modified copy of the tree.
|
||
|
|
||
|
The root of the schedule tree can be obtained using the following function.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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<isl_schedule_node_from_extension> creates a tree with an extension
|
||
|
node as root.
|
||
|
|
||
|
Schedule nodes can be copied and freed using the following functions.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
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 <isl/schedule_node.h>
|
||
|
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<isl_schedule_node_get_type> returns the type of
|
||
|
the node, while C<isl_schedule_node_get_parent_type> returns
|
||
|
type of the parent of the node, which is required to exist.
|
||
|
The function C<isl_schedule_node_get_schedule> 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/schedule_node.h>
|
||
|
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_root(
|
||
|
__isl_take isl_schedule_node *node);
|
||
|
__isl_give isl_schedule_node *isl_schedule_node_ancestor(
|
||
|
__isl_take isl_schedule_node *node,
|
||
|
int generation);
|
||
|
int 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_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<isl_schedule_node_ancestor>, 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<isl_schedule_node_get_shared_ancestor>.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
int isl_schedule_node_get_tree_depth(
|
||
|
__isl_keep isl_schedule_node *node);
|
||
|
int isl_schedule_node_get_child_position(
|
||
|
__isl_keep isl_schedule_node *node);
|
||
|
int 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/schedule.h>
|
||
|
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/schedule_node.h>
|
||
|
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 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/schedule_node.h>
|
||
|
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/schedule.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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);
|
||
|
unsigned 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);
|
||
|
__isl_give isl_union_set *
|
||
|
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_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<isl_schedule_node_band_get_space> returns the space
|
||
|
of the partial schedule of the band.
|
||
|
The function C<isl_schedule_node_band_get_partial_schedule_union_map>
|
||
|
returns a representation of the partial schedule of the band node
|
||
|
in the form of an C<isl_union_map>.
|
||
|
The coincident and permutable properties are set by
|
||
|
C<isl_schedule_constraints_compute_schedule> 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<isl_ast_loop_type> is one of C<isl_ast_loop_default>,
|
||
|
C<isl_ast_loop_atomic>, C<isl_ast_loop_unroll> or C<isl_ast_loop_separate>.
|
||
|
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</"AST Generation Options (Schedule Tree)">.
|
||
|
The functions C<isl_schedule_node_band_member_get_ast_loop_type>
|
||
|
and C<isl_schedule_node_band_member_get_isolate_ast_loop_type>
|
||
|
may return C<isl_ast_loop_error> if an error occurs.
|
||
|
The AST build options govern how an AST is generated for
|
||
|
the individual schedule dimensions during AST generation.
|
||
|
See L</"AST Generation Options (Schedule Tree)">.
|
||
|
The isolate option for the given node can be extracted from these
|
||
|
AST build options using the function
|
||
|
C<isl_schedule_node_band_get_ast_isolate_option>.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__isl_give isl_set *
|
||
|
isl_schedule_node_context_get_context(
|
||
|
__isl_keep isl_schedule_node *node);
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__isl_give isl_union_set *
|
||
|
isl_schedule_node_domain_get_domain(
|
||
|
__isl_keep isl_schedule_node *node);
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__isl_give isl_union_map *
|
||
|
isl_schedule_node_extension_get_extension(
|
||
|
__isl_keep isl_schedule_node *node);
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__isl_give isl_union_set *
|
||
|
isl_schedule_node_filter_get_filter(
|
||
|
__isl_keep isl_schedule_node *node);
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__isl_give isl_set *isl_schedule_node_guard_get_guard(
|
||
|
__isl_keep isl_schedule_node *node);
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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<isl_multi_union_pw_aff>,
|
||
|
an C<isl_union_pw_multi_aff> or C<isl_union_map> representation of
|
||
|
partial schedules related to the node.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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<isl_schedule_node_get_prefix_schedule_multi_union_pw_aff>,
|
||
|
C<isl_schedule_node_get_prefix_schedule_union_pw_multi_aff>
|
||
|
and C<isl_schedule_node_get_prefix_schedule_union_map>
|
||
|
return a relative ordering on the domain elements that reach the given
|
||
|
node determined by its ancestors.
|
||
|
The function C<isl_schedule_node_get_prefix_schedule_relation>
|
||
|
additionally includes the domain constraints in the result.
|
||
|
The function C<isl_schedule_node_get_subtree_schedule_union_map>
|
||
|
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<isl_schedule_node_get_subtree_schedule_union_map>
|
||
|
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/schedule_node.h>
|
||
|
__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<isl_schedule_node_get_prefix_schedule_union_map> can be obtained
|
||
|
using the following function.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
int 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/schedule_node.h>
|
||
|
__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<isl_schedule_node_get_domain>
|
||
|
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<isl_schedule_node> points to and
|
||
|
the results points to the new node.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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<group_id> 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 function can be used to flatten a nested
|
||
|
sequence.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__isl_give isl_schedule_node *
|
||
|
isl_schedule_node_sequence_splice_child(
|
||
|
__isl_take isl_schedule_node *node, int pos);
|
||
|
|
||
|
That is, given a sequence node C<node> that has another sequence node
|
||
|
in its child at position C<pos> (in particular, the child of that filter
|
||
|
node is a sequence node), attach the children of that other sequence
|
||
|
node as children of C<node>, replacing the original child at position
|
||
|
C<pos>.
|
||
|
|
||
|
The partial schedule of a band node can be scaled (down) or reduced using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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<isl_multi_union_pw_aff> with a domain that is a superset
|
||
|
of the domain of the partial schedule using
|
||
|
the following function.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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/schedule_node.h>
|
||
|
__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<isl_schedule_node_band_tile> 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<tile_scale_tile_loops> option specifies whether the tile
|
||
|
loops iterators should be scaled by the tile sizes.
|
||
|
If the C<tile_shift_point_loops> 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/schedule_node.h>
|
||
|
__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<pos> dimensions of
|
||
|
the schedule of C<node> while the inner band contains the remaining dimensions.
|
||
|
The schedules of the two band nodes live in anonymous spaces.
|
||
|
The loop AST generation type options and the isolate option
|
||
|
are split over the the two band nodes.
|
||
|
|
||
|
A band node can be moved down to the leaves of the subtree rooted
|
||
|
at the band node using the following function.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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<node> in the original tree.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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<node>
|
||
|
into those that satisfy C<filter> and those that do not and
|
||
|
arranges for the elements that do satisfy the filter to be
|
||
|
executed before (in case of C<isl_schedule_node_order_before>)
|
||
|
or after (in case of C<isl_schedule_node_order_after>)
|
||
|
those that do not. The order is imposed by
|
||
|
a sequence node, possibly reusing the grandparent of C<node>
|
||
|
on two copies of the subtree attached to the original C<node>.
|
||
|
Both copies are simplified with respect to their filter.
|
||
|
|
||
|
Return a pointer to the copy of the subtree that does not
|
||
|
satisfy C<filter>. If there is no such copy (because all
|
||
|
reaching domain elements satisfy the filter), then return
|
||
|
the original pointer.
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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<graft> tree into the tree containing C<node>
|
||
|
such that it is executed before (in case of C<isl_schedule_node_graft_before>)
|
||
|
or after (in case of C<isl_schedule_node_graft_after>) C<node>.
|
||
|
The root node of C<graft>
|
||
|
should be an extension node where the domain of the extension
|
||
|
is the flat product of all outer band nodes of C<node>.
|
||
|
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<graft> may not be anchored.
|
||
|
|
||
|
The schedule tree of C<node> is modified to include an extension node
|
||
|
corresponding to the root node of C<graft> as a child of the original
|
||
|
parent of C<node>. The original node that C<node> points to and the
|
||
|
child of the root node of C<graft> are attached to this extension node
|
||
|
through a sequence, with appropriate filters and with the child
|
||
|
of C<graft> appearing before or after the original C<node>.
|
||
|
|
||
|
If C<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
|
||
|
C<node> pointed to in the original tree.
|
||
|
|
||
|
A representation of the schedule node can be printed using
|
||
|
|
||
|
#include <isl/schedule_node.h>
|
||
|
__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<isl_schedule_node_to_str> prints the schedule node in block format.
|
||
|
|
||
|
=head2 Dependence Analysis
|
||
|
|
||
|
C<isl> contains specialized functionality for performing
|
||
|
array dataflow analysis. That is, given a I<sink> access relation,
|
||
|
a collection of possible I<source> accesses and
|
||
|
a collection of I<kill> accesses,
|
||
|
C<isl> 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<must>
|
||
|
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/flow.h>
|
||
|
__isl_give isl_union_flow *
|
||
|
isl_union_access_info_compute_flow(
|
||
|
__isl_take isl_union_access_info *access);
|
||
|
|
||
|
The input C<isl_union_access_info> object describes the sink
|
||
|
access relations, the source access relations and a schedule,
|
||
|
while the output C<isl_union_flow> object describes
|
||
|
the resulting dependence relations and the subsets of the
|
||
|
sink relations for which no source was found.
|
||
|
|
||
|
An C<isl_union_access_info> is created, modified, copied and freed using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/flow.h>
|
||
|
__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<isl_union_access_info_set_may_source>
|
||
|
do not need to include the must sources set by
|
||
|
C<isl_union_access_info_set_must_source> as a subset.
|
||
|
The kills set by C<isl_union_access_info_set_kill> 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<isl_union_access_info_from_sink> is empty.
|
||
|
The current schedule is determined by the last call to either
|
||
|
C<isl_union_access_info_set_schedule> or
|
||
|
C<isl_union_access_info_set_schedule_map>.
|
||
|
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<isl_union_access_info> object can be read from input
|
||
|
using the following function.
|
||
|
|
||
|
#include <isl/flow.h>
|
||
|
__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<isl_union_access_info> can be obtained using
|
||
|
|
||
|
#include <isl/flow.h>
|
||
|
__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<isl_union_access_info_to_str> prints the information in flow format.
|
||
|
|
||
|
The output of C<isl_union_access_info_compute_flow> can be examined,
|
||
|
copied, and freed using the following functions.
|
||
|
|
||
|
#include <isl/flow.h>
|
||
|
__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<isl_union_flow_get_must_dependence>
|
||
|
relates domain elements of must sources to domain elements of the sink.
|
||
|
The relation returned by C<isl_union_flow_get_may_dependence>
|
||
|
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<isl_union_flow_get_full_must_dependence>
|
||
|
relates domain elements of must sources to pairs of domain elements of the sink
|
||
|
and accessed data elements.
|
||
|
The relation returned by C<isl_union_flow_get_full_may_dependence>
|
||
|
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<isl_union_flow_get_must_no_source> is the subset
|
||
|
of the sink relation for which no dependences have been found.
|
||
|
The relation returned by C<isl_union_flow_get_may_no_source> 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<isl_union_flow_get_must_dependence>.
|
||
|
|
||
|
A representation of the information contained in an object
|
||
|
of type C<isl_union_flow> can be obtained using
|
||
|
|
||
|
#include <isl/flow.h>
|
||
|
__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<isl_union_flow_to_str> prints the information in flow format.
|
||
|
|
||
|
=head3 Low-level Interface
|
||
|
|
||
|
A lower-level interface is provided by the following functions.
|
||
|
|
||
|
#include <isl/flow.h>
|
||
|
|
||
|
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);
|
||
|
void isl_flow_free(__isl_take isl_flow *deps);
|
||
|
|
||
|
The function C<isl_access_info_compute_flow> 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<isl_access_info>, which can
|
||
|
be created through a call to C<isl_access_info_alloc>.
|
||
|
The arguments to this functions are the sink access relation
|
||
|
C<sink>, a token C<sink_user> 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<int (*)(void *first, void *second)>.
|
||
|
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<n> be the number of loops shared by
|
||
|
the two accesses. If C<first> precedes C<second> 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<isl_access_info> object by performing
|
||
|
(at most) C<max_source> calls to C<isl_access_info_add_source>.
|
||
|
C<must> indicates whether the source is a I<must> access
|
||
|
or a I<may> access. Note that a multi-valued access relation
|
||
|
should only be marked I<must> if every iteration in the domain
|
||
|
of the relation accesses I<all> elements in its image.
|
||
|
The C<source_user> token is again used to identify
|
||
|
the source access. The range of the source access relation
|
||
|
C<source> should have the same dimension as the range
|
||
|
of the sink access relation.
|
||
|
The C<isl_access_info_free> function should usually not be
|
||
|
called explicitly, because it is already called implicitly by
|
||
|
C<isl_access_info_compute_flow>.
|
||
|
|
||
|
The result of the dependence analysis is collected in an
|
||
|
C<isl_flow>. 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<may> accesses.
|
||
|
The relations containing these elements can be obtained through
|
||
|
calls to C<isl_flow_get_no_source>, the first with C<must> set
|
||
|
and the second with C<must> unset.
|
||
|
In the case of standard flow dependence analysis,
|
||
|
with the sink a read and the sources I<must> 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<isl_flow_foreach>. This function will call the user-specified
|
||
|
callback function C<fn> for each B<non-empty> 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<must> or I<may> dependence, a token
|
||
|
identifying the source and an additional C<void *> with value
|
||
|
equal to the third argument of the C<isl_flow_foreach> call.
|
||
|
A dependence is marked I<must> if it originates from a I<must>
|
||
|
source and if it is not followed by any I<may> sources.
|
||
|
|
||
|
After finishing with an C<isl_flow>, the user should call
|
||
|
C<isl_flow_free> 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<isl> provides the following
|
||
|
function.
|
||
|
|
||
|
#include <isl/flow.h>
|
||
|
|
||
|
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<isl_access_info_set_restrict> should be called
|
||
|
before calling C<isl_access_info_compute_flow> and registers a callback function
|
||
|
that will be called any time C<isl> 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<isl_access_info_set_restrict>.
|
||
|
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<NULL>.
|
||
|
An C<isl_restriction> object can be created, freed and inspected
|
||
|
using the following functions.
|
||
|
|
||
|
#include <isl/flow.h>
|
||
|
|
||
|
__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<isl_restriction_none> and C<isl_restriction_empty> are special
|
||
|
cases of C<isl_restriction_input>. C<isl_restriction_none>
|
||
|
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<isl_restriction_empty> 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/schedule.h>
|
||
|
__isl_give isl_schedule *
|
||
|
isl_schedule_constraints_compute_schedule(
|
||
|
__isl_take isl_schedule_constraints *sc);
|
||
|
|
||
|
The function C<isl_schedule_constraints_compute_schedule> 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<validity> dependences and I<proximity> dependences.
|
||
|
By default, the algorithm used to construct the schedule is similar
|
||
|
to that of C<Pluto>.
|
||
|
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<isl_schedule_constraints> object can be constructed
|
||
|
and manipulated using the following functions.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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<isl_schedule_constraints> object created by
|
||
|
C<isl_schedule_constraints_on_domain> does not impose any constraints.
|
||
|
That is, it has an empty set of dependences.
|
||
|
The function C<isl_schedule_constraints_set_context> 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<isl_schedule_constraints_set_validity> replaces the
|
||
|
validity dependences, mapping domain elements I<i> to domain
|
||
|
elements that should be scheduled after I<i>.
|
||
|
The function C<isl_schedule_constraints_set_coincidence> replaces the
|
||
|
coincidence dependences, mapping domain elements I<i> to domain
|
||
|
elements that should be scheduled together with I<I>, if possible.
|
||
|
The function C<isl_schedule_constraints_set_proximity> replaces the
|
||
|
proximity dependences, mapping domain elements I<i> to domain
|
||
|
elements that should be scheduled either before I<I>
|
||
|
or as early as possible after I<i>.
|
||
|
|
||
|
The function C<isl_schedule_constraints_set_conditional_validity>
|
||
|
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<tags>. 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<isl_schedule_constraints_compute_schedule> 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<isl_schedule_constraints> object can be inspected
|
||
|
using the following functions.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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<isl_schedule_constraints> object can be read from input
|
||
|
using the following functions.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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<isl_schedule_constraints> object can be printed
|
||
|
using the following functions.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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<isl_union_set_compute_schedule> is discouraged.
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
__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</"Schedule Trees">.
|
||
|
|
||
|
=head3 Options
|
||
|
|
||
|
#include <isl/schedule.h>
|
||
|
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.
|
||
|
|
||
|
=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<schedule_serialize_sccs> 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<schedule_whole_component> 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<schedule_serialize_sccs> options is set, then
|
||
|
the C<schedule_maximize_band_depth> option therefore has no effect.
|
||
|
|
||
|
=item * schedule_maximize_coincidence
|
||
|
|
||
|
This option is only effective if the C<schedule_whole_component>
|
||
|
option is turned off.
|
||
|
If the C<schedule_maximize_coincidence> 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<ISL_SCHEDULE_ALGORITHM_ISL>
|
||
|
and C<ISL_SCHEDULE_ALGORITHM_FEAUTRIER>.
|
||
|
|
||
|
=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<isl_schedule_get_map>
|
||
|
will treat set nodes in the same way as sequence nodes.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head2 AST Generation
|
||
|
|
||
|
This section describes the C<isl> 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<isl_union_map>, an AST is generated
|
||
|
that visits all the elements in the domain of the C<isl_union_map>
|
||
|
according to the lexicographic order of the corresponding image
|
||
|
element(s). If the range of the C<isl_union_map> 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<order>
|
||
|
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/ast_build.h>
|
||
|
__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<set> argument is usually a parameter set with zero or more parameters.
|
||
|
In fact, when creating an AST using C<isl_ast_build_node_from_schedule>,
|
||
|
this set is required to be a parameter set.
|
||
|
An C<isl_ast_build> created using C<isl_ast_build_alloc> does not
|
||
|
specify any parameter constraints.
|
||
|
More C<isl_ast_build> functions are described in L</"Nested AST Generation">
|
||
|
and L</"Fine-grained Control over AST Generation">.
|
||
|
Finally, the AST itself can be constructed using one of the following
|
||
|
functions.
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
__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 <isl/ast.h>
|
||
|
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<isl_ast_node_for>,
|
||
|
C<isl_ast_node_if>,
|
||
|
C<isl_ast_node_block>,
|
||
|
C<isl_ast_node_mark> or
|
||
|
C<isl_ast_node_user>.
|
||
|
An C<isl_ast_node_for> represents a for node.
|
||
|
An C<isl_ast_node_if> represents an if node.
|
||
|
An C<isl_ast_node_block> represents a compound node.
|
||
|
An C<isl_ast_node_mark> introduces a mark in the AST.
|
||
|
An C<isl_ast_node_user> 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/ast.h>
|
||
|
__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<isl_ast_for> is considered degenerate if it is known to execute
|
||
|
exactly once.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__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(
|
||
|
__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(
|
||
|
__isl_keep isl_ast_node *node);
|
||
|
|
||
|
__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<isl_ast_node_mark_get_id> returns the identifier of the mark.
|
||
|
C<isl_ast_node_mark_get_node> returns the child node that is being marked.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__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/ast.h>
|
||
|
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<isl_bool_true> if the children
|
||
|
of the given node should be visited and C<isl_bool_false> if they should not.
|
||
|
It should return C<isl_bool_error> in case of failure, in which case
|
||
|
the entire traversal is aborted.
|
||
|
|
||
|
Each of the returned C<isl_ast_expr>s can in turn be inspected using
|
||
|
the following functions.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
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<isl_ast_expr_op>,
|
||
|
C<isl_ast_expr_id> or
|
||
|
C<isl_ast_expr_int>.
|
||
|
An C<isl_ast_expr_op> represents the result of an operation.
|
||
|
An C<isl_ast_expr_id> represents an identifier.
|
||
|
An C<isl_ast_expr_int> represents an integer value.
|
||
|
|
||
|
Each type of expression has its own additional properties.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
enum isl_ast_op_type isl_ast_expr_get_op_type(
|
||
|
__isl_keep isl_ast_expr *expr);
|
||
|
int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr);
|
||
|
__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_op_type(
|
||
|
__isl_keep isl_ast_expr *expr,
|
||
|
isl_stat (*fn)(enum isl_ast_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_op_type type,
|
||
|
void *user), void *user);
|
||
|
|
||
|
C<isl_ast_expr_get_op_type> returns the type of the operation
|
||
|
performed. C<isl_ast_expr_get_op_n_arg> returns the number of
|
||
|
arguments. C<isl_ast_expr_get_op_arg> returns the specified
|
||
|
argument.
|
||
|
C<isl_ast_expr_foreach_ast_op_type> calls C<fn> for each distinct
|
||
|
C<isl_ast_op_type> that appears in C<expr>.
|
||
|
C<isl_ast_node_foreach_ast_op_type> does the same for each distinct
|
||
|
C<isl_ast_op_type> that appears in C<node>.
|
||
|
The operation type is one of the following.
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item C<isl_ast_op_and>
|
||
|
|
||
|
Logical I<and> of two arguments.
|
||
|
Both arguments can be evaluated.
|
||
|
|
||
|
=item C<isl_ast_op_and_then>
|
||
|
|
||
|
Logical I<and> of two arguments.
|
||
|
The second argument can only be evaluated if the first evaluates to true.
|
||
|
|
||
|
=item C<isl_ast_op_or>
|
||
|
|
||
|
Logical I<or> of two arguments.
|
||
|
Both arguments can be evaluated.
|
||
|
|
||
|
=item C<isl_ast_op_or_else>
|
||
|
|
||
|
Logical I<or> of two arguments.
|
||
|
The second argument can only be evaluated if the first evaluates to false.
|
||
|
|
||
|
=item C<isl_ast_op_max>
|
||
|
|
||
|
Maximum of two or more arguments.
|
||
|
|
||
|
=item C<isl_ast_op_min>
|
||
|
|
||
|
Minimum of two or more arguments.
|
||
|
|
||
|
=item C<isl_ast_op_minus>
|
||
|
|
||
|
Change sign.
|
||
|
|
||
|
=item C<isl_ast_op_add>
|
||
|
|
||
|
Sum of two arguments.
|
||
|
|
||
|
=item C<isl_ast_op_sub>
|
||
|
|
||
|
Difference of two arguments.
|
||
|
|
||
|
=item C<isl_ast_op_mul>
|
||
|
|
||
|
Product of two arguments.
|
||
|
|
||
|
=item C<isl_ast_op_div>
|
||
|
|
||
|
Exact division. That is, the result is known to be an integer.
|
||
|
|
||
|
=item C<isl_ast_op_fdiv_q>
|
||
|
|
||
|
Result of integer division, rounded towards negative
|
||
|
infinity.
|
||
|
|
||
|
=item C<isl_ast_op_pdiv_q>
|
||
|
|
||
|
Result of integer division, where dividend is known to be non-negative.
|
||
|
|
||
|
=item C<isl_ast_op_pdiv_r>
|
||
|
|
||
|
Remainder of integer division, where dividend is known to be non-negative.
|
||
|
|
||
|
=item C<isl_ast_op_zdiv_r>
|
||
|
|
||
|
Equal to zero iff the remainder on integer division is zero.
|
||
|
|
||
|
=item C<isl_ast_op_cond>
|
||
|
|
||
|
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<a ? b : c> in C.
|
||
|
|
||
|
=item C<isl_ast_op_select>
|
||
|
|
||
|
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<a * b + (1 - a) * c> in C.
|
||
|
|
||
|
=item C<isl_ast_op_eq>
|
||
|
|
||
|
Equality relation.
|
||
|
|
||
|
=item C<isl_ast_op_le>
|
||
|
|
||
|
Less than or equal relation.
|
||
|
|
||
|
=item C<isl_ast_op_lt>
|
||
|
|
||
|
Less than relation.
|
||
|
|
||
|
=item C<isl_ast_op_ge>
|
||
|
|
||
|
Greater than or equal relation.
|
||
|
|
||
|
=item C<isl_ast_op_gt>
|
||
|
|
||
|
Greater than relation.
|
||
|
|
||
|
=item C<isl_ast_op_call>
|
||
|
|
||
|
A function call.
|
||
|
The number of arguments of the C<isl_ast_expr> is one more than
|
||
|
the number of arguments in the function call, the first argument
|
||
|
representing the function being called.
|
||
|
|
||
|
=item C<isl_ast_op_access>
|
||
|
|
||
|
An array access.
|
||
|
The number of arguments of the C<isl_ast_expr> is one more than
|
||
|
the number of index expressions in the array access, the first argument
|
||
|
representing the array being accessed.
|
||
|
|
||
|
=item C<isl_ast_op_member>
|
||
|
|
||
|
A member access.
|
||
|
This operation has two arguments, a structure and the name of
|
||
|
the member of the structure being accessed.
|
||
|
|
||
|
=back
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__isl_give isl_id *isl_ast_expr_get_id(
|
||
|
__isl_keep isl_ast_expr *expr);
|
||
|
|
||
|
Return the identifier represented by the AST expression.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__isl_give isl_val *isl_ast_expr_get_val(
|
||
|
__isl_keep isl_ast_expr *expr);
|
||
|
|
||
|
Return the integer represented by the AST expression.
|
||
|
|
||
|
=head3 Properties of ASTs
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
isl_bool isl_ast_expr_is_equal(
|
||
|
__isl_keep isl_ast_expr *expr1,
|
||
|
__isl_keep isl_ast_expr *expr2);
|
||
|
|
||
|
Check if two C<isl_ast_expr>s are equal to each other.
|
||
|
|
||
|
=head3 Manipulating and printing the AST
|
||
|
|
||
|
AST nodes can be copied and freed using the following functions.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__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/ast.h>
|
||
|
__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<isl_ast_build>.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__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<isl_ast_expr_address_of> can be applied to an
|
||
|
C<isl_ast_expr> of type C<isl_ast_op_access> only. It is meant
|
||
|
to represent the address of the C<isl_ast_expr_access>. The function
|
||
|
C<isl_ast_expr_and_then> as well as C<isl_ast_expr_or_else> are short-circuit
|
||
|
versions of C<isl_ast_expr_and> and C<isl_ast_expr_or>, respectively.
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
__isl_give isl_ast_expr *isl_ast_build_expr_from_set(
|
||
|
__isl_keep isl_ast_build *build,
|
||
|
__isl_take isl_set *set);
|
||
|
__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff(
|
||
|
__isl_keep isl_ast_build *build,
|
||
|
__isl_take isl_pw_aff *pa);
|
||
|
__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 <set> and
|
||
|
the domains of C<pa>, C<mpa> and C<pma> should correspond
|
||
|
to the schedule space of C<build>.
|
||
|
The tuple id of C<mpa> or C<pma> is used as the array being accessed or
|
||
|
the function being called.
|
||
|
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<isl_ast_expr>.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__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<expr> at position C<pos> by C<arg>.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__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<isl_ast_expr_substitute_ids> replaces the
|
||
|
subexpressions of C<expr> of type C<isl_ast_expr_id>
|
||
|
by the corresponding expression in C<id2expr>, if there is any.
|
||
|
|
||
|
|
||
|
User specified data can be attached to an C<isl_ast_node> and obtained
|
||
|
from the same C<isl_ast_node> using the following functions.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__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/ast.h>
|
||
|
__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<isl_ast_expr_to_C_str> and
|
||
|
C<isl_ast_node_to_C_str> 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/ast.h>
|
||
|
__isl_give isl_printer *isl_ast_op_type_set_print_name(
|
||
|
__isl_take isl_printer *p,
|
||
|
enum isl_ast_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_op_type_print_macro(
|
||
|
enum isl_ast_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<isl_ast_node> in C<ISL_FORMAT_C>,
|
||
|
C<isl> may print out an AST that makes use of macros such
|
||
|
as C<floord>, C<min> and C<max>.
|
||
|
The names of these macros may be modified by a call
|
||
|
to C<isl_ast_op_type_set_print_name>. The user-specified
|
||
|
names are associated to the printer object.
|
||
|
C<isl_ast_op_type_print_macro> prints out the macro
|
||
|
corresponding to a specific C<isl_ast_op_type>.
|
||
|
If the print-macro-once option is set, then a given macro definition
|
||
|
is only printed once to any given printer object.
|
||
|
C<isl_ast_expr_print_macros> scans the C<isl_ast_expr>
|
||
|
for subexpressions where these macros would be used and prints
|
||
|
out the required macro definitions.
|
||
|
Essentially, C<isl_ast_expr_print_macros> calls
|
||
|
C<isl_ast_expr_foreach_ast_op_type> with C<isl_ast_op_type_print_macro>
|
||
|
as function argument.
|
||
|
C<isl_ast_node_print_macros> does the same
|
||
|
for expressions in its C<isl_ast_node> argument.
|
||
|
C<isl_ast_node_print>, C<isl_ast_node_for_print> and
|
||
|
C<isl_ast_node_if_print> print an C<isl_ast_node>
|
||
|
in C<ISL_FORMAT_C>, but allow for some extra control
|
||
|
through an C<isl_ast_print_options> object.
|
||
|
This object can be created using the following functions.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__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<isl_ast_print_options_set_print_user>
|
||
|
is called whenever a node of type C<isl_ast_node_user> needs to
|
||
|
be printed.
|
||
|
The callback set by C<isl_ast_print_options_set_print_for>
|
||
|
is called whenever a node of type C<isl_ast_node_for> needs to
|
||
|
be printed.
|
||
|
Note that C<isl_ast_node_for_print> will I<not> call the
|
||
|
callback set by C<isl_ast_print_options_set_print_for> on the node
|
||
|
on which C<isl_ast_node_for_print> is called, but only on nested
|
||
|
nodes of type C<isl_ast_node_for>. It is therefore safe to
|
||
|
call C<isl_ast_node_for_print> from within the callback set by
|
||
|
C<isl_ast_print_options_set_print_for>.
|
||
|
|
||
|
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 as blocks if these
|
||
|
blocks cannot be safely omitted.
|
||
|
For example, a C<for> node with one body node will not be
|
||
|
surrounded with braces in C<ISL_FORMAT_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);
|
||
|
|
||
|
=head3 Options
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
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_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<isl_ast_op_fdiv_q>
|
||
|
operators, but no C<isl_ast_op_pdiv_q> or
|
||
|
C<isl_ast_op_pdiv_r> operators.
|
||
|
If this option is turned on, then C<isl> will try to convert
|
||
|
some of the C<isl_ast_op_fdiv_q> operators to (expressions containing)
|
||
|
C<isl_ast_op_pdiv_q> or C<isl_ast_op_pdiv_r> operators.
|
||
|
|
||
|
=item * ast_build_detect_min_max
|
||
|
|
||
|
If this option is turned on, then C<isl> 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<isl_ast_build_set_create_leaf> 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<ISL_AST_BUILD_SEPARATION_BOUNDS_IMPLICIT>
|
||
|
then all (possibly implicit) bounds on the current dimension will
|
||
|
be used during separation.
|
||
|
If this option is set to C<ISL_AST_BUILD_SEPARATION_BOUNDS_EXPLICIT>
|
||
|
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</"Schedule Trees">).
|
||
|
|
||
|
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<isl_schedule_node_band_member_set_ast_loop_type>.
|
||
|
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<atomic>, C<separate>
|
||
|
or C<unroll> in the options
|
||
|
set by C<isl_schedule_node_band_set_ast_build_options>.
|
||
|
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<atomic>
|
||
|
|
||
|
When this option is specified, the AST generator will make
|
||
|
sure that a given domains 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<atomic> nor C<separate> is specified, then the AST generator
|
||
|
may produce either of these two results or some intermediate form.
|
||
|
|
||
|
=item C<separate>
|
||
|
|
||
|
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<atomic> option.
|
||
|
|
||
|
=item C<unroll>
|
||
|
|
||
|
When this option is specified, the AST generator will
|
||
|
I<completely> 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<isolate> 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<isolate> 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<isolate> 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<isolate> space and as range the regular
|
||
|
C<atomic>, C<separate> or C<unroll> space.
|
||
|
This option may also be set directly using
|
||
|
C<isl_schedule_node_band_member_set_isolate_ast_loop_type>.
|
||
|
The atomic/separate/unroll choice for the remaining part is determined
|
||
|
by the regular C<atomic>, C<separate> or C<unroll> option.
|
||
|
Since the C<isolate> 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<isl_ast_build_node_from_schedule_map>, the options
|
||
|
that control how an AST is created from the individual schedule
|
||
|
dimensions are stored in the C<isl_ast_build>.
|
||
|
They can be set using the following function.
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
__isl_give isl_ast_build *
|
||
|
isl_ast_build_set_options(
|
||
|
__isl_take isl_ast_build *control,
|
||
|
__isl_take isl_union_map *options);
|
||
|
|
||
|
The options are encoded in an C<isl_union_map>.
|
||
|
The domain of this union relation refers to the schedule domain,
|
||
|
i.e., the range of the schedule passed
|
||
|
to C<isl_ast_build_node_from_schedule_map>.
|
||
|
In the case of nested AST generation (see L</"Nested AST Generation">),
|
||
|
the domain of C<options> 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. In case of nested AST generation
|
||
|
(see L</"Nested AST Generation">), 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<separation_class>
|
||
|
|
||
|
B<This option has been deprecated. Use the isolate option on
|
||
|
schedule trees instead.>
|
||
|
|
||
|
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<separate>
|
||
|
|
||
|
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<atomic> option.
|
||
|
|
||
|
=item C<atomic>
|
||
|
|
||
|
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<atomic> nor C<separate> is specified, then the AST generator
|
||
|
may produce either of these two results or some intermediate form.
|
||
|
|
||
|
=item C<unroll>
|
||
|
|
||
|
This is a single-dimensional space representing the schedule dimension(s)
|
||
|
that should be I<completely> 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<isl_ast_build> object can be used to control
|
||
|
various aspects of the AST generation process.
|
||
|
In case of AST construction using
|
||
|
C<isl_ast_build_node_from_schedule_map>,
|
||
|
the most prominent way of control is through ``options'',
|
||
|
as explained above.
|
||
|
|
||
|
Additional control is available through the following functions.
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
__isl_give isl_ast_build *
|
||
|
isl_ast_build_set_iterators(
|
||
|
__isl_take isl_ast_build *control,
|
||
|
__isl_take isl_id_list *iterators);
|
||
|
|
||
|
The function C<isl_ast_build_set_iterators> allows the user to
|
||
|
specify a list of iterator C<isl_id>s 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 C<isl_id>s equal to the largest dimension of the input domains
|
||
|
may be required.
|
||
|
If the number of provided C<isl_id>s is insufficient, then additional
|
||
|
names are automatically generated.
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
__isl_give isl_ast_build *
|
||
|
isl_ast_build_set_create_leaf(
|
||
|
__isl_take isl_ast_build *control,
|
||
|
__isl_give isl_ast_node *(*fn)(
|
||
|
__isl_take isl_ast_build *build,
|
||
|
void *user), void *user);
|
||
|
|
||
|
The
|
||
|
C<isl_ast_build_set_create_leaf> 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<build> argument contains the current state of the C<isl_ast_build>.
|
||
|
To ease nested AST generation (see L</"Nested AST Generation">),
|
||
|
all control information that is
|
||
|
specific to the current AST generation such as the options and
|
||
|
the callbacks has been removed from this C<isl_ast_build>.
|
||
|
The callback would typically return the result of a nested
|
||
|
AST generation or a
|
||
|
user defined node created using the following function.
|
||
|
|
||
|
#include <isl/ast.h>
|
||
|
__isl_give isl_ast_node *isl_ast_node_alloc_user(
|
||
|
__isl_take isl_ast_expr *expr);
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
__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<isl_ast_build_set_at_each_domain> will
|
||
|
be called for each domain AST node.
|
||
|
The callbacks set by C<isl_ast_build_set_before_each_for>
|
||
|
and C<isl_ast_build_set_after_each_for> 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<isl_ast_build_set_before_each_for> is called before the for
|
||
|
node is actually constructed, it is only passed an C<isl_ast_build>.
|
||
|
The returned C<isl_id> will be added as an annotation (using
|
||
|
C<isl_ast_node_set_annotation>) to the constructed for node.
|
||
|
In particular, if the user has also specified an C<after_each_for>
|
||
|
callback, then the annotation can be retrieved from the node passed to
|
||
|
that callback using C<isl_ast_node_get_annotation>.
|
||
|
The callbacks set by C<isl_ast_build_set_before_each_mark>
|
||
|
and C<isl_ast_build_set_after_each_mark> 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<isl_ast_build_set_before_each_mark>
|
||
|
is called before the mark AST node is actually constructed, it is passed
|
||
|
the identifier of the mark node.
|
||
|
All callbacks should C<NULL> (or -1) on failure.
|
||
|
The given C<isl_ast_build> can be used to create new
|
||
|
C<isl_ast_expr> objects using C<isl_ast_build_expr_from_pw_aff>
|
||
|
or C<isl_ast_build_call_from_pw_multi_aff>.
|
||
|
|
||
|
=head3 Nested AST Generation
|
||
|
|
||
|
C<isl> allows the user to create an AST within the context
|
||
|
of another AST. These nested ASTs are created using the
|
||
|
same C<isl_ast_build_node_from_schedule_map> function that is used to create
|
||
|
the outer AST. The C<build> argument should be an C<isl_ast_build>
|
||
|
passed to a callback set by
|
||
|
C<isl_ast_build_set_create_leaf>.
|
||
|
The space of the range of the C<schedule> 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<isl_ast_build_get_schedule> below.
|
||
|
In practice, the new schedule is typically
|
||
|
created by calling C<isl_union_map_range_product> on the old schedule
|
||
|
and some extra piece of the schedule.
|
||
|
The space of the schedule domain is also available from
|
||
|
the C<isl_ast_build>.
|
||
|
|
||
|
#include <isl/ast_build.h>
|
||
|
__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<isl_ast_build_get_schedule> 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<isl_ast_build_get_schedule_space> can be used
|
||
|
to create a set for C<isl_ast_build_restrict> to intersect
|
||
|
with the current build. In particular, the set passed to
|
||
|
C<isl_ast_build_restrict> can have additional parameters.
|
||
|
The ids of the set dimensions in the space returned by
|
||
|
C<isl_ast_build_get_schedule_space> 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<isl_ast_build_get_schedule> having any particular value.
|
||
|
|
||
|
=head1 Applications
|
||
|
|
||
|
Although C<isl> is mainly meant to be used as a library,
|
||
|
it also contains some basic applications that use some
|
||
|
of the functionality of C<isl>.
|
||
|
For applications that take one or more polytopes or polyhedra
|
||
|
as input, this input may be specified in either the L<isl format>
|
||
|
or the L<PolyLib format>.
|
||
|
|
||
|
=head2 C<isl_polyhedron_sample>
|
||
|
|
||
|
C<isl_polyhedron_sample> 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<isl_pip>
|
||
|
|
||
|
C<isl_pip> takes the same input as the C<example> program
|
||
|
from the C<piplib> 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<isl> currently does not have its own output format, the output
|
||
|
is just a dump of the internal state.
|
||
|
|
||
|
=head2 C<isl_polyhedron_minimize>
|
||
|
|
||
|
C<isl_polyhedron_minimize> 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<isl_polytope_scan>
|
||
|
|
||
|
Given a polytope, C<isl_polytope_scan> prints
|
||
|
all integer points in the polytope.
|
||
|
|
||
|
=head2 C<isl_flow>
|
||
|
|
||
|
Given an C<isl_union_access_info> object as input,
|
||
|
C<isl_flow> prints out the corresponding dependences,
|
||
|
as computed by C<isl_union_access_info_compute_flow>.
|
||
|
|
||
|
=head2 C<isl_codegen>
|
||
|
|
||
|
Given either a schedule tree or a sequence consisting of
|
||
|
a schedule map, a context set and an options relation,
|
||
|
C<isl_codegen> 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<isl_schedule>
|
||
|
|
||
|
Given an C<isl_schedule_constraints> object as input,
|
||
|
C<isl_schedule> prints out a schedule that satisfies the given
|
||
|
constraints.
|