[Polly] Update isl to isl-0.27-77-g99a07a03 (#179350)
Update isl to include https://repo.or.cz/isl.git/commit/99a07a039237f11bccc1ef80a7b6cc76ae5f98c5 which fixes #177808 Thanks @skimo-openhub for the fix and @Andarwinux for the crash report Fixes: #177808
This commit is contained in:
parent
350b138313
commit
cdab38f776
2
polly/lib/External/isl/GIT_HEAD_ID
vendored
2
polly/lib/External/isl/GIT_HEAD_ID
vendored
@ -1 +1 @@
|
||||
isl-0.27
|
||||
isl-0.27-77-g99a07a03
|
||||
|
||||
23
polly/lib/External/isl/doc/user.pod
vendored
23
polly/lib/External/isl/doc/user.pod
vendored
@ -469,8 +469,8 @@ Use the system clang libraries installed in I<path>.
|
||||
|
||||
=back
|
||||
|
||||
It is best to use the latest release of the clang libraries (16.0),
|
||||
although any release since 3.5 should work as well.
|
||||
It is best to use the latest release of the clang libraries (21.1),
|
||||
although any release since 3.9 should work as well.
|
||||
Note that if you build the clang libraries from source,
|
||||
then you need to make sure they are also installed (using C<make install>).
|
||||
If the compiler that was used to compile the clang libraries
|
||||
@ -5247,6 +5247,9 @@ return true if the objects are not the same.
|
||||
__isl_keep isl_multi_id *mi2);
|
||||
|
||||
#include <isl/val.h>
|
||||
isl_bool isl_multi_val_is_equal(
|
||||
__isl_keep isl_multi_val *mv1,
|
||||
__isl_keep isl_multi_val *mv2);
|
||||
isl_bool isl_multi_val_plain_is_equal(
|
||||
__isl_keep isl_multi_val *mv1,
|
||||
__isl_keep isl_multi_val *mv2);
|
||||
@ -6450,9 +6453,17 @@ variables, then the result of these operations is currently undefined.
|
||||
__isl_take isl_map *map,
|
||||
__isl_take isl_map_list *list);
|
||||
|
||||
#include <isl/union_set.h>
|
||||
__isl_give isl_union_set *
|
||||
isl_union_set_plain_unshifted_simple_hull(
|
||||
__isl_take isl_union_set *uset);
|
||||
|
||||
#include <isl/union_map.h>
|
||||
__isl_give isl_union_map *isl_union_map_simple_hull(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *
|
||||
isl_union_map_plain_unshifted_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.
|
||||
@ -6553,6 +6564,14 @@ The box can be copied and freed using the following functions.
|
||||
__isl_null isl_fixed_box *isl_fixed_box_free(
|
||||
__isl_take isl_fixed_box *box);
|
||||
|
||||
The following function checks whether two C<isl_fixed_box> objects
|
||||
are obviously the same.
|
||||
|
||||
#include <isl/fixed_box.h>
|
||||
isl_bool isl_fixed_box_plain_is_equal(
|
||||
__isl_keep isl_fixed_box *box1,
|
||||
__isl_keep isl_fixed_box *box2);
|
||||
|
||||
An object of type C<isl_fixed_box> can be read from input
|
||||
using the following function.
|
||||
|
||||
|
||||
2
polly/lib/External/isl/include/isl/arg.h
vendored
2
polly/lib/External/isl/include/isl/arg.h
vendored
@ -288,6 +288,8 @@ struct isl_args {
|
||||
#define ISL_ARG_ALL (1 << 0)
|
||||
#define ISL_ARG_SKIP_HELP (1 << 1)
|
||||
|
||||
int isl_arg_str_list_append(int *n, const char ***list, const char *s);
|
||||
|
||||
void isl_args_set_defaults(struct isl_args *args, void *opt);
|
||||
void isl_args_free(struct isl_args *args, void *opt);
|
||||
int isl_args_parse(struct isl_args *args, int argc, char **argv, void *opt,
|
||||
|
||||
14
polly/lib/External/isl/include/isl/cpp-checked.h
vendored
14
polly/lib/External/isl/include/isl/cpp-checked.h
vendored
@ -1742,6 +1742,7 @@ class fixed_box {
|
||||
inline boolean is_valid() const;
|
||||
inline isl::checked::multi_aff offset() const;
|
||||
inline isl::checked::multi_aff get_offset() const;
|
||||
inline boolean plain_is_equal(const isl::checked::fixed_box &box2) const;
|
||||
inline isl::checked::multi_val size() const;
|
||||
inline isl::checked::multi_val get_size() const;
|
||||
inline isl::checked::space space() const;
|
||||
@ -2586,6 +2587,7 @@ class multi_val {
|
||||
inline isl::checked::multi_val flat_range_product(isl::checked::multi_val multi2) const;
|
||||
inline boolean has_range_tuple_id() const;
|
||||
inline boolean involves_nan() const;
|
||||
inline boolean is_equal(const isl::checked::multi_val &mv2) const;
|
||||
inline isl::checked::val_list list() const;
|
||||
inline isl::checked::val_list get_list() const;
|
||||
inline isl::checked::multi_val max(isl::checked::multi_val multi2) const;
|
||||
@ -9037,6 +9039,12 @@ isl::checked::multi_aff fixed_box::get_offset() const
|
||||
return offset();
|
||||
}
|
||||
|
||||
boolean fixed_box::plain_is_equal(const isl::checked::fixed_box &box2) const
|
||||
{
|
||||
auto res = isl_fixed_box_plain_is_equal(get(), box2.get());
|
||||
return manage(res);
|
||||
}
|
||||
|
||||
isl::checked::multi_val fixed_box::size() const
|
||||
{
|
||||
auto res = isl_fixed_box_get_size(get());
|
||||
@ -12843,6 +12851,12 @@ boolean multi_val::involves_nan() const
|
||||
return manage(res);
|
||||
}
|
||||
|
||||
boolean multi_val::is_equal(const isl::checked::multi_val &mv2) const
|
||||
{
|
||||
auto res = isl_multi_val_is_equal(get(), mv2.get());
|
||||
return manage(res);
|
||||
}
|
||||
|
||||
isl::checked::val_list multi_val::list() const
|
||||
{
|
||||
auto res = isl_multi_val_get_list(get());
|
||||
|
||||
26
polly/lib/External/isl/include/isl/cpp.h
vendored
26
polly/lib/External/isl/include/isl/cpp.h
vendored
@ -1808,6 +1808,7 @@ class fixed_box {
|
||||
inline bool is_valid() const;
|
||||
inline isl::multi_aff offset() const;
|
||||
inline isl::multi_aff get_offset() const;
|
||||
inline bool plain_is_equal(const isl::fixed_box &box2) const;
|
||||
inline isl::multi_val size() const;
|
||||
inline isl::multi_val get_size() const;
|
||||
inline isl::space space() const;
|
||||
@ -2652,6 +2653,7 @@ class multi_val {
|
||||
inline isl::multi_val flat_range_product(isl::multi_val multi2) const;
|
||||
inline bool has_range_tuple_id() const;
|
||||
inline bool involves_nan() const;
|
||||
inline bool is_equal(const isl::multi_val &mv2) const;
|
||||
inline isl::val_list list() const;
|
||||
inline isl::val_list get_list() const;
|
||||
inline isl::multi_val max(isl::multi_val multi2) const;
|
||||
@ -10929,6 +10931,18 @@ isl::multi_aff fixed_box::get_offset() const
|
||||
return offset();
|
||||
}
|
||||
|
||||
bool fixed_box::plain_is_equal(const isl::fixed_box &box2) const
|
||||
{
|
||||
if (!ptr || box2.is_null())
|
||||
exception::throw_invalid("NULL input", __FILE__, __LINE__);
|
||||
auto saved_ctx = ctx();
|
||||
options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
|
||||
auto res = isl_fixed_box_plain_is_equal(get(), box2.get());
|
||||
if (res < 0)
|
||||
exception::throw_last_error(saved_ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
isl::multi_val fixed_box::size() const
|
||||
{
|
||||
if (!ptr)
|
||||
@ -17158,6 +17172,18 @@ bool multi_val::involves_nan() const
|
||||
return res;
|
||||
}
|
||||
|
||||
bool multi_val::is_equal(const isl::multi_val &mv2) const
|
||||
{
|
||||
if (!ptr || mv2.is_null())
|
||||
exception::throw_invalid("NULL input", __FILE__, __LINE__);
|
||||
auto saved_ctx = ctx();
|
||||
options_scoped_set_on_error saved_on_error(saved_ctx, exception::on_error);
|
||||
auto res = isl_multi_val_is_equal(get(), mv2.get());
|
||||
if (res < 0)
|
||||
exception::throw_last_error(saved_ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
isl::val_list multi_val::list() const
|
||||
{
|
||||
if (!ptr)
|
||||
|
||||
18
polly/lib/External/isl/include/isl/ctx.h
vendored
18
polly/lib/External/isl/include/isl/ctx.h
vendored
@ -12,6 +12,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isl/arg.h>
|
||||
|
||||
@ -85,7 +86,7 @@ typedef enum {
|
||||
isl_stat_error = -1,
|
||||
isl_stat_ok = 0
|
||||
} isl_stat;
|
||||
isl_stat isl_stat_non_null(void *obj);
|
||||
isl_stat isl_stat_non_null(const void *obj);
|
||||
typedef enum {
|
||||
isl_bool_error = -1,
|
||||
isl_bool_false = 0,
|
||||
@ -240,6 +241,21 @@ isl_stat prefix ## _set_ ## field(isl_ctx *ctx, const char *val) \
|
||||
return isl_stat_ok; \
|
||||
}
|
||||
|
||||
#define ISL_CTX_APPEND_STR_LIST_DEF(prefix,st,args,field_n,field) \
|
||||
isl_stat prefix ## _append_ ## field(isl_ctx *ctx, const char *val) \
|
||||
{ \
|
||||
st *options; \
|
||||
options = isl_ctx_peek_ ## prefix(ctx); \
|
||||
if (!options) \
|
||||
isl_die(ctx, isl_error_invalid, \
|
||||
"isl_ctx does not reference " #prefix, \
|
||||
return isl_stat_error); \
|
||||
if (!val) \
|
||||
return isl_stat_error; \
|
||||
return isl_arg_str_list_append(&options->field_n, \
|
||||
&options->field, val); \
|
||||
}
|
||||
|
||||
#define ISL_CTX_GET_BOOL_DEF(prefix,st,args,field) \
|
||||
ISL_CTX_GET_INT_DEF(prefix,st,args,field)
|
||||
|
||||
|
||||
@ -31,6 +31,10 @@ __isl_give isl_multi_val *isl_fixed_box_get_size(__isl_keep isl_fixed_box *box);
|
||||
__isl_give isl_fixed_box *isl_fixed_box_copy(__isl_keep isl_fixed_box *box);
|
||||
__isl_null isl_fixed_box *isl_fixed_box_free(__isl_take isl_fixed_box *box);
|
||||
|
||||
__isl_export
|
||||
isl_bool isl_fixed_box_plain_is_equal(__isl_keep isl_fixed_box *box1,
|
||||
__isl_keep isl_fixed_box *box2);
|
||||
|
||||
__isl_constructor
|
||||
__isl_give isl_fixed_box *isl_fixed_box_read_from_str(isl_ctx *ctx,
|
||||
const char *str);
|
||||
|
||||
@ -82,6 +82,8 @@ __isl_give isl_union_map *isl_union_map_remove_redundancies(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *isl_union_map_simple_hull(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *isl_union_map_plain_unshifted_simple_hull(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_export
|
||||
__isl_give isl_union_map *isl_union_map_coalesce(
|
||||
__isl_take isl_union_map *umap);
|
||||
|
||||
@ -52,6 +52,8 @@ __isl_give isl_union_set *isl_union_set_remove_redundancies(
|
||||
__isl_take isl_union_set *uset);
|
||||
__isl_give isl_union_set *isl_union_set_simple_hull(
|
||||
__isl_take isl_union_set *uset);
|
||||
__isl_give isl_union_set *isl_union_set_plain_unshifted_simple_hull(
|
||||
__isl_take isl_union_set *uset);
|
||||
__isl_export
|
||||
__isl_give isl_union_set *isl_union_set_coalesce(
|
||||
__isl_take isl_union_set *uset);
|
||||
|
||||
3
polly/lib/External/isl/include/isl/val.h
vendored
3
polly/lib/External/isl/include/isl/val.h
vendored
@ -153,6 +153,9 @@ __isl_give isl_printer *isl_printer_print_val(__isl_take isl_printer *p,
|
||||
void isl_val_dump(__isl_keep isl_val *v);
|
||||
__isl_give char *isl_val_to_str(__isl_keep isl_val *v);
|
||||
|
||||
__isl_export
|
||||
isl_bool isl_multi_val_is_equal(__isl_keep isl_multi_val *mv1,
|
||||
__isl_keep isl_multi_val *mv2);
|
||||
isl_bool isl_multi_val_is_zero(__isl_keep isl_multi_val *mv);
|
||||
|
||||
__isl_overload
|
||||
|
||||
@ -25,7 +25,7 @@ LT_INIT
|
||||
AX_DETECT_CLANG
|
||||
|
||||
AC_SUBST([CONFIG_STATUS_DEPENDENCIES], [$LLVM_CONFIG])
|
||||
AC_CONFIG_HEADERS(isl_config.h)
|
||||
AC_CONFIG_HEADERS(isl_config.h include/isl-interface/config.h)
|
||||
AC_CONFIG_FILES(Makefile)
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
4
polly/lib/External/isl/interface/cpp.cc
vendored
4
polly/lib/External/isl/interface/cpp.cc
vendored
@ -689,12 +689,12 @@ std::string cpp_type_printer::generate_callback_args(int arg, QualType type,
|
||||
int num_params;
|
||||
|
||||
callback = generator::extract_prototype(type);
|
||||
num_params = callback->getNumArgs();
|
||||
num_params = callback->getNumParams();
|
||||
if (cpp)
|
||||
num_params--;
|
||||
|
||||
for (long i = 0; i < num_params; i++) {
|
||||
QualType type = callback->getArgType(i);
|
||||
QualType type = callback->getParamType(i);
|
||||
|
||||
if (cpp)
|
||||
type_str += param(arg + 1 + i, type);
|
||||
|
||||
@ -38,52 +38,24 @@
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <type_traits>
|
||||
#ifdef HAVE_ADT_OWNINGPTR_H
|
||||
#include <llvm/ADT/OwningPtr.h>
|
||||
#else
|
||||
#include <memory>
|
||||
#endif
|
||||
#ifdef HAVE_LLVM_OPTION_ARG_H
|
||||
#include <llvm/Option/Arg.h>
|
||||
#endif
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
#include <llvm/Support/CommandLine.h>
|
||||
#ifdef HAVE_TARGETPARSER_HOST_H
|
||||
#include <llvm/TargetParser/Host.h>
|
||||
#else
|
||||
#include <llvm/Support/Host.h>
|
||||
#endif
|
||||
#include <llvm/Support/ManagedStatic.h>
|
||||
#include <clang/AST/ASTContext.h>
|
||||
#include <clang/AST/ASTConsumer.h>
|
||||
#include <clang/Basic/Builtins.h>
|
||||
#include <clang/Basic/FileSystemOptions.h>
|
||||
#include <clang/Basic/FileManager.h>
|
||||
#include <clang/Basic/TargetOptions.h>
|
||||
#include <clang/Basic/TargetInfo.h>
|
||||
#include <clang/Basic/Version.h>
|
||||
#include <clang/Driver/Compilation.h>
|
||||
#include <clang/Driver/Driver.h>
|
||||
#include <clang/Driver/Tool.h>
|
||||
#include <clang/Frontend/CompilerInstance.h>
|
||||
#include <clang/Frontend/CompilerInvocation.h>
|
||||
#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H
|
||||
#include <clang/Basic/DiagnosticOptions.h>
|
||||
#else
|
||||
#include <clang/Frontend/DiagnosticOptions.h>
|
||||
#endif
|
||||
#include <clang/Basic/FileSystemOptions.h>
|
||||
#include <clang/Frontend/CompilerInstance.h>
|
||||
#include <clang/Frontend/TextDiagnosticPrinter.h>
|
||||
#include <clang/Frontend/Utils.h>
|
||||
#include <clang/Lex/HeaderSearch.h>
|
||||
#ifdef HAVE_LEX_PREPROCESSOROPTIONS_H
|
||||
#include <clang/Lex/PreprocessorOptions.h>
|
||||
#else
|
||||
#include <clang/Frontend/PreprocessorOptions.h>
|
||||
#endif
|
||||
#include <clang/Lex/Preprocessor.h>
|
||||
#include <clang/Parse/ParseAST.h>
|
||||
#include <clang/Sema/Sema.h>
|
||||
|
||||
#include "isl-interface/clang_wrap.h"
|
||||
|
||||
#include "extract_interface.h"
|
||||
#include "generator.h"
|
||||
#include "python.h"
|
||||
@ -98,10 +70,6 @@ using namespace clang::driver;
|
||||
using namespace llvm::opt;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ADT_OWNINGPTR_H
|
||||
#define unique_ptr llvm::OwningPtr
|
||||
#endif
|
||||
|
||||
static llvm::cl::opt<string> InputFilename(llvm::cl::Positional,
|
||||
llvm::cl::Required, llvm::cl::desc("<input file>"));
|
||||
static llvm::cl::list<string> Includes("I",
|
||||
@ -113,9 +81,6 @@ static llvm::cl::opt<string> OutputLanguage(llvm::cl::Required,
|
||||
llvm::cl::desc("Bindings to generate"),
|
||||
llvm::cl::value_desc("name"));
|
||||
|
||||
static const char *ResourceDir =
|
||||
CLANG_PREFIX "/lib/clang/" CLANG_VERSION_STRING;
|
||||
|
||||
/* Does decl have an attribute of the following form?
|
||||
*
|
||||
* __attribute__((annotate("name")))
|
||||
@ -179,360 +144,59 @@ struct MyASTConsumer : public ASTConsumer {
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef USE_ARRAYREF
|
||||
|
||||
#ifdef HAVE_CXXISPRODUCTION
|
||||
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
|
||||
{
|
||||
return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
|
||||
"", false, false, Diags);
|
||||
}
|
||||
#elif defined(HAVE_ISPRODUCTION)
|
||||
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
|
||||
{
|
||||
return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
|
||||
"", false, Diags);
|
||||
}
|
||||
#elif defined(DRIVER_CTOR_TAKES_DEFAULTIMAGENAME)
|
||||
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
|
||||
{
|
||||
return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
|
||||
"", Diags);
|
||||
}
|
||||
#else
|
||||
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
|
||||
{
|
||||
return new Driver(binary, llvm::sys::getDefaultTargetTriple(), Diags);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace clang { namespace driver { class Job; } }
|
||||
|
||||
/* Clang changed its API from 3.5 to 3.6 and once more in 3.7.
|
||||
* We fix this with a simple overloaded function here.
|
||||
/* A class specializing the Wrap helper class for
|
||||
* extracting the isl interface.
|
||||
*/
|
||||
struct ClangAPI {
|
||||
static Job *command(Job *J) { return J; }
|
||||
static Job *command(Job &J) { return &J; }
|
||||
static Command *command(Command &C) { return &C; }
|
||||
struct Extractor : public isl::clang::Wrap {
|
||||
virtual TextDiagnosticPrinter *construct_printer() override;
|
||||
virtual void suppress_errors(DiagnosticsEngine &Diags) override;
|
||||
virtual void add_paths(HeaderSearchOptions &HSO) override;
|
||||
virtual void add_macros(PreprocessorOptions &PO) override;
|
||||
virtual void handle_error() override;
|
||||
virtual bool handle(CompilerInstance *Clang) override;
|
||||
};
|
||||
|
||||
#ifdef CREATE_FROM_ARGS_TAKES_ARRAYREF
|
||||
|
||||
/* Call CompilerInvocation::CreateFromArgs with the right arguments.
|
||||
* In this case, an ArrayRef<const char *>.
|
||||
/* Construct a TextDiagnosticPrinter.
|
||||
*/
|
||||
static void create_from_args(CompilerInvocation &invocation,
|
||||
const ArgStringList *args, DiagnosticsEngine &Diags)
|
||||
TextDiagnosticPrinter *Extractor::construct_printer(void)
|
||||
{
|
||||
CompilerInvocation::CreateFromArgs(invocation, *args, Diags);
|
||||
return new TextDiagnosticPrinter(llvm::errs(), getDiagnosticOptions());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Call CompilerInvocation::CreateFromArgs with the right arguments.
|
||||
* In this case, two "const char *" pointers.
|
||||
/* Suppress any errors, if needed.
|
||||
*/
|
||||
static void create_from_args(CompilerInvocation &invocation,
|
||||
const ArgStringList *args, DiagnosticsEngine &Diags)
|
||||
void Extractor::suppress_errors(DiagnosticsEngine &Diags)
|
||||
{
|
||||
CompilerInvocation::CreateFromArgs(invocation, args->data() + 1,
|
||||
args->data() + args->size(),
|
||||
Diags);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CLANG_SYSROOT
|
||||
/* Set sysroot if required.
|
||||
*
|
||||
* If CLANG_SYSROOT is defined, then set it to this value.
|
||||
/* Add required search paths to "HSO".
|
||||
*/
|
||||
static void set_sysroot(ArgStringList &args)
|
||||
void Extractor::add_paths(HeaderSearchOptions &HSO)
|
||||
{
|
||||
args.push_back("-isysroot");
|
||||
args.push_back(CLANG_SYSROOT);
|
||||
for (llvm::cl::list<string>::size_type i = 0; i < Includes.size(); ++i)
|
||||
isl::clang::add_path(HSO, Includes[i]);
|
||||
}
|
||||
#else
|
||||
/* Set sysroot if required.
|
||||
*
|
||||
* If CLANG_SYSROOT is not defined, then it does not need to be set.
|
||||
|
||||
/* Add required macro definitions to "PO".
|
||||
*/
|
||||
static void set_sysroot(ArgStringList &args)
|
||||
void Extractor::add_macros(PreprocessorOptions &PO)
|
||||
{
|
||||
PO.addMacroDef("__isl_give=__attribute__((annotate(\"isl_give\")))");
|
||||
PO.addMacroDef("__isl_keep=__attribute__((annotate(\"isl_keep\")))");
|
||||
PO.addMacroDef("__isl_take=__attribute__((annotate(\"isl_take\")))");
|
||||
PO.addMacroDef("__isl_export=__attribute__((annotate(\"isl_export\")))");
|
||||
PO.addMacroDef("__isl_overload="
|
||||
"__attribute__((annotate(\"isl_overload\"))) "
|
||||
"__attribute__((annotate(\"isl_export\")))");
|
||||
PO.addMacroDef("__isl_constructor=__attribute__((annotate(\"isl_constructor\"))) __attribute__((annotate(\"isl_export\")))");
|
||||
PO.addMacroDef("__isl_subclass(super)=__attribute__((annotate(\"isl_subclass(\" #super \")\"))) __attribute__((annotate(\"isl_export\")))");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create a CompilerInvocation object that stores the command line
|
||||
* arguments constructed by the driver.
|
||||
* The arguments are mainly useful for setting up the system include
|
||||
* paths on newer clangs and on some platforms.
|
||||
/* Handle an error opening the file.
|
||||
*/
|
||||
static CompilerInvocation *construct_invocation(const char *filename,
|
||||
DiagnosticsEngine &Diags)
|
||||
void Extractor::handle_error()
|
||||
{
|
||||
const char *binary = CLANG_PREFIX"/bin/clang";
|
||||
const unique_ptr<Driver> driver(construct_driver(binary, Diags));
|
||||
std::vector<const char *> Argv;
|
||||
Argv.push_back(binary);
|
||||
Argv.push_back(filename);
|
||||
const unique_ptr<Compilation> compilation(
|
||||
driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
|
||||
JobList &Jobs = compilation->getJobs();
|
||||
|
||||
Command *cmd = cast<Command>(ClangAPI::command(*Jobs.begin()));
|
||||
if (strcmp(cmd->getCreator().getName(), "clang"))
|
||||
return NULL;
|
||||
|
||||
ArgStringList args = cmd->getArguments();
|
||||
set_sysroot(args);
|
||||
|
||||
CompilerInvocation *invocation = new CompilerInvocation;
|
||||
create_from_args(*invocation, &args, Diags);
|
||||
return invocation;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static CompilerInvocation *construct_invocation(const char *filename,
|
||||
DiagnosticsEngine &Diags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H
|
||||
|
||||
static TextDiagnosticPrinter *construct_printer(void)
|
||||
{
|
||||
return new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static TextDiagnosticPrinter *construct_printer(void)
|
||||
{
|
||||
DiagnosticOptions DO;
|
||||
return new TextDiagnosticPrinter(llvm::errs(), DO);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CREATETARGETINFO_TAKES_SHARED_PTR
|
||||
|
||||
static TargetInfo *create_target_info(CompilerInstance *Clang,
|
||||
DiagnosticsEngine &Diags)
|
||||
{
|
||||
shared_ptr<TargetOptions> TO = Clang->getInvocation().TargetOpts;
|
||||
TO->Triple = llvm::sys::getDefaultTargetTriple();
|
||||
return TargetInfo::CreateTargetInfo(Diags, TO);
|
||||
}
|
||||
|
||||
#elif defined(CREATETARGETINFO_TAKES_POINTER)
|
||||
|
||||
static TargetInfo *create_target_info(CompilerInstance *Clang,
|
||||
DiagnosticsEngine &Diags)
|
||||
{
|
||||
TargetOptions &TO = Clang->getTargetOpts();
|
||||
TO.Triple = llvm::sys::getDefaultTargetTriple();
|
||||
return TargetInfo::CreateTargetInfo(Diags, &TO);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static TargetInfo *create_target_info(CompilerInstance *Clang,
|
||||
DiagnosticsEngine &Diags)
|
||||
{
|
||||
TargetOptions &TO = Clang->getTargetOpts();
|
||||
TO.Triple = llvm::sys::getDefaultTargetTriple();
|
||||
return TargetInfo::CreateTargetInfo(Diags, TO);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CREATEDIAGNOSTICS_TAKES_ARG
|
||||
|
||||
static void create_diagnostics(CompilerInstance *Clang)
|
||||
{
|
||||
Clang->createDiagnostics(0, NULL, construct_printer());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void create_diagnostics(CompilerInstance *Clang)
|
||||
{
|
||||
Clang->createDiagnostics(construct_printer());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CREATEPREPROCESSOR_TAKES_TUKIND
|
||||
|
||||
static void create_preprocessor(CompilerInstance *Clang)
|
||||
{
|
||||
Clang->createPreprocessor(TU_Complete);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void create_preprocessor(CompilerInstance *Clang)
|
||||
{
|
||||
Clang->createPreprocessor();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ADDPATH_TAKES_4_ARGUMENTS
|
||||
|
||||
/* Add "Path" to the header search options.
|
||||
*
|
||||
* Do not take into account sysroot, i.e., set ignoreSysRoot to true.
|
||||
*/
|
||||
void add_path(HeaderSearchOptions &HSO, string Path)
|
||||
{
|
||||
HSO.AddPath(Path, frontend::Angled, false, true);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Add "Path" to the header search options.
|
||||
*
|
||||
* Do not take into account sysroot, i.e., set IsSysRootRelative to false.
|
||||
*/
|
||||
void add_path(HeaderSearchOptions &HSO, string Path)
|
||||
{
|
||||
HSO.AddPath(Path, frontend::Angled, true, false, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETMAINFILEID
|
||||
|
||||
template <typename T>
|
||||
static void create_main_file_id(SourceManager &SM, const T &file)
|
||||
{
|
||||
SM.setMainFileID(SM.createFileID(file, SourceLocation(),
|
||||
SrcMgr::C_User));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void create_main_file_id(SourceManager &SM, const FileEntry *file)
|
||||
{
|
||||
SM.createMainFileID(file);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SETLANGDEFAULTS_TAKES_5_ARGUMENTS
|
||||
|
||||
#include "set_lang_defaults_arg4.h"
|
||||
|
||||
static void set_lang_defaults(CompilerInstance *Clang)
|
||||
{
|
||||
PreprocessorOptions &PO = Clang->getPreprocessorOpts();
|
||||
TargetOptions &TO = Clang->getTargetOpts();
|
||||
llvm::Triple T(TO.Triple);
|
||||
SETLANGDEFAULTS::setLangDefaults(Clang->getLangOpts(), IK_C, T,
|
||||
setLangDefaultsArg4(PO),
|
||||
LangStandard::lang_unspecified);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void set_lang_defaults(CompilerInstance *Clang)
|
||||
{
|
||||
CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
|
||||
LangStandard::lang_unspecified);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SETINVOCATION_TAKES_SHARED_PTR
|
||||
|
||||
static void set_invocation(CompilerInstance *Clang,
|
||||
CompilerInvocation *invocation)
|
||||
{
|
||||
Clang->setInvocation(std::make_shared<CompilerInvocation>(*invocation));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void set_invocation(CompilerInstance *Clang,
|
||||
CompilerInvocation *invocation)
|
||||
{
|
||||
Clang->setInvocation(invocation);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Helper function for ignore_error that only gets enabled if T
|
||||
* (which is either const FileEntry * or llvm::ErrorOr<const FileEntry *>)
|
||||
* has getError method, i.e., if it is llvm::ErrorOr<const FileEntry *>.
|
||||
*/
|
||||
template <class T>
|
||||
static const FileEntry *ignore_error_helper(const T obj, int,
|
||||
int[1][sizeof(obj.getError())])
|
||||
{
|
||||
return *obj;
|
||||
}
|
||||
|
||||
/* Helper function for ignore_error that is always enabled,
|
||||
* but that only gets selected if the variant above is not enabled,
|
||||
* i.e., if T is const FileEntry *.
|
||||
*/
|
||||
template <class T>
|
||||
static const FileEntry *ignore_error_helper(const T obj, long, void *)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* Given either a const FileEntry * or a llvm::ErrorOr<const FileEntry *>,
|
||||
* extract out the const FileEntry *.
|
||||
*/
|
||||
template <class T>
|
||||
static const FileEntry *ignore_error(const T obj)
|
||||
{
|
||||
return ignore_error_helper(obj, 0, NULL);
|
||||
}
|
||||
|
||||
/* This is identical to std::void_t in C++17.
|
||||
*/
|
||||
template< class... >
|
||||
using void_t = void;
|
||||
|
||||
/* A template class with value true if "T" has a getFileRef method.
|
||||
*/
|
||||
template <class T, class = void>
|
||||
struct HasGetFileRef : public std::false_type {};
|
||||
template <class T>
|
||||
struct HasGetFileRef<T, ::void_t<decltype(&T::getFileRef)>> :
|
||||
public std::true_type {};
|
||||
|
||||
/* Return the FileEntryRef/FileEntry corresponding to the given file name
|
||||
* in the given compiler instances, ignoring any error.
|
||||
*
|
||||
* If T (= FileManager) has a getFileRef method, then call that and
|
||||
* return a FileEntryRef.
|
||||
* Otherwise, call getFile and return a FileEntry (pointer).
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<HasGetFileRef<T>::value, bool>::type = true>
|
||||
static auto getFile(T& obj, const std::string &filename)
|
||||
-> decltype(*obj.getFileRef(filename))
|
||||
{
|
||||
auto file = obj.getFileRef(filename);
|
||||
assert(file);
|
||||
return *file;
|
||||
}
|
||||
template <typename T,
|
||||
typename std::enable_if<!HasGetFileRef<T>::value, bool>::type = true>
|
||||
static const FileEntry *getFile(T& obj, const std::string &filename)
|
||||
{
|
||||
const FileEntry *file = ignore_error(obj.getFile(filename));
|
||||
assert(file);
|
||||
return file;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/* Create an interface generator for the selected language and
|
||||
@ -567,64 +231,36 @@ static void generate(MyASTConsumer &consumer, SourceManager &SM)
|
||||
gen->generate();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
/* Parse the current source file, returning true if no error was encountered.
|
||||
*/
|
||||
bool Extractor::handle(CompilerInstance *Clang)
|
||||
{
|
||||
llvm::cl::ParseCommandLineOptions(argc, argv);
|
||||
|
||||
CompilerInstance *Clang = new CompilerInstance();
|
||||
create_diagnostics(Clang);
|
||||
DiagnosticsEngine &Diags = Clang->getDiagnostics();
|
||||
Diags.setSuppressSystemWarnings(true);
|
||||
TargetInfo *target = create_target_info(Clang, Diags);
|
||||
Clang->setTarget(target);
|
||||
set_lang_defaults(Clang);
|
||||
CompilerInvocation *invocation =
|
||||
construct_invocation(InputFilename.c_str(), Diags);
|
||||
if (invocation)
|
||||
set_invocation(Clang, invocation);
|
||||
Clang->createFileManager();
|
||||
Clang->createSourceManager(Clang->getFileManager());
|
||||
HeaderSearchOptions &HSO = Clang->getHeaderSearchOpts();
|
||||
LangOptions &LO = Clang->getLangOpts();
|
||||
PreprocessorOptions &PO = Clang->getPreprocessorOpts();
|
||||
HSO.ResourceDir = ResourceDir;
|
||||
|
||||
for (llvm::cl::list<string>::size_type i = 0; i < Includes.size(); ++i)
|
||||
add_path(HSO, Includes[i]);
|
||||
|
||||
PO.addMacroDef("__isl_give=__attribute__((annotate(\"isl_give\")))");
|
||||
PO.addMacroDef("__isl_keep=__attribute__((annotate(\"isl_keep\")))");
|
||||
PO.addMacroDef("__isl_take=__attribute__((annotate(\"isl_take\")))");
|
||||
PO.addMacroDef("__isl_export=__attribute__((annotate(\"isl_export\")))");
|
||||
PO.addMacroDef("__isl_overload="
|
||||
"__attribute__((annotate(\"isl_overload\"))) "
|
||||
"__attribute__((annotate(\"isl_export\")))");
|
||||
PO.addMacroDef("__isl_constructor=__attribute__((annotate(\"isl_constructor\"))) __attribute__((annotate(\"isl_export\")))");
|
||||
PO.addMacroDef("__isl_subclass(super)=__attribute__((annotate(\"isl_subclass(\" #super \")\"))) __attribute__((annotate(\"isl_export\")))");
|
||||
|
||||
create_preprocessor(Clang);
|
||||
Preprocessor &PP = Clang->getPreprocessor();
|
||||
|
||||
PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(), LO);
|
||||
|
||||
auto file = getFile(Clang->getFileManager(), InputFilename);
|
||||
create_main_file_id(Clang->getSourceManager(), file);
|
||||
|
||||
Clang->createASTContext();
|
||||
MyASTConsumer consumer;
|
||||
Sema *sema = new Sema(PP, Clang->getASTContext(), consumer);
|
||||
|
||||
Diags.getClient()->BeginSourceFile(LO, &PP);
|
||||
DiagnosticsEngine &Diags = Clang->getDiagnostics();
|
||||
Diags.getClient()->BeginSourceFile(Clang->getLangOpts(), &PP);
|
||||
ParseAST(*sema);
|
||||
Diags.getClient()->EndSourceFile();
|
||||
|
||||
generate(consumer, Clang->getSourceManager());
|
||||
|
||||
delete sema;
|
||||
delete Clang;
|
||||
|
||||
return !Diags.hasErrorOccurred();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
llvm::cl::ParseCommandLineOptions(argc, argv);
|
||||
|
||||
Extractor extractor;
|
||||
bool ok = extractor.invoke(InputFilename.c_str());
|
||||
|
||||
llvm::llvm_shutdown();
|
||||
|
||||
if (Diags.hasErrorOccurred())
|
||||
if (!ok)
|
||||
return EXIT_FAILURE;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -796,7 +796,7 @@ const FunctionProtoType *generator::extract_prototype(QualType type)
|
||||
*/
|
||||
int generator::prototype_n_args(QualType type)
|
||||
{
|
||||
return extract_prototype(type)->getNumArgs();
|
||||
return extract_prototype(type)->getNumParams();
|
||||
}
|
||||
|
||||
/* Return the function name suffix for the type of "param".
|
||||
|
||||
425
polly/lib/External/isl/interface/include/isl-interface/clang_wrap.h
vendored
Normal file
425
polly/lib/External/isl/interface/include/isl-interface/clang_wrap.h
vendored
Normal file
@ -0,0 +1,425 @@
|
||||
#include <isl-interface/config.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef HAVE_LLVM_OPTION_ARG_H
|
||||
#include <llvm/Option/Arg.h>
|
||||
#endif
|
||||
#ifdef HAVE_TARGETPARSER_HOST_H
|
||||
#include <llvm/TargetParser/Host.h>
|
||||
#else
|
||||
#include <llvm/Support/Host.h>
|
||||
#endif
|
||||
#include <clang/AST/ASTContext.h>
|
||||
#include <clang/Basic/Builtins.h>
|
||||
#include <clang/Basic/DiagnosticOptions.h>
|
||||
#include <clang/Basic/FileManager.h>
|
||||
#include <clang/Basic/TargetOptions.h>
|
||||
#include <clang/Basic/TargetInfo.h>
|
||||
#include <clang/Basic/Version.h>
|
||||
#include <clang/Driver/Compilation.h>
|
||||
#include <clang/Driver/Driver.h>
|
||||
#include <clang/Driver/Tool.h>
|
||||
#include <clang/Frontend/CompilerInstance.h>
|
||||
#include <clang/Frontend/CompilerInvocation.h>
|
||||
#include <clang/Frontend/TextDiagnosticPrinter.h>
|
||||
#include <clang/Lex/HeaderSearch.h>
|
||||
#include <clang/Lex/PreprocessorOptions.h>
|
||||
#include <clang/Lex/Preprocessor.h>
|
||||
|
||||
namespace clang { namespace driver { class Job; } }
|
||||
|
||||
namespace isl {
|
||||
namespace clang {
|
||||
|
||||
using namespace ::clang;
|
||||
using namespace ::clang::driver;
|
||||
#ifdef HAVE_LLVM_OPTION_ARG_H
|
||||
using namespace llvm::opt;
|
||||
#endif
|
||||
|
||||
#ifndef ISL_CLANG_RESOURCE_DIR
|
||||
#define ISL_CLANG_RESOURCE_DIR \
|
||||
ISL_CLANG_PREFIX "/lib/clang/" CLANG_VERSION_STRING
|
||||
#endif
|
||||
static const char *ResourceDir = ISL_CLANG_RESOURCE_DIR;
|
||||
|
||||
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
|
||||
{
|
||||
return new Driver(binary, llvm::sys::getDefaultTargetTriple(), Diags);
|
||||
}
|
||||
|
||||
/* Clang changed its API from 3.5 to 3.6 and once more in 3.7.
|
||||
* We fix this with a simple overloaded function here.
|
||||
*/
|
||||
struct ClangAPI {
|
||||
static Job *command(Job *J) { return J; }
|
||||
static Job *command(Job &J) { return &J; }
|
||||
static Command *command(Command &C) { return &C; }
|
||||
};
|
||||
|
||||
#ifdef CREATE_FROM_ARGS_TAKES_ARRAYREF
|
||||
|
||||
/* Call CompilerInvocation::CreateFromArgs with the right arguments.
|
||||
* In this case, an ArrayRef<const char *>.
|
||||
*/
|
||||
static void create_from_args(CompilerInvocation &invocation,
|
||||
const ArgStringList *args, DiagnosticsEngine &Diags)
|
||||
{
|
||||
CompilerInvocation::CreateFromArgs(invocation, *args, Diags);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Call CompilerInvocation::CreateFromArgs with the right arguments.
|
||||
* In this case, two "const char *" pointers.
|
||||
*/
|
||||
static void create_from_args(CompilerInvocation &invocation,
|
||||
const ArgStringList *args, DiagnosticsEngine &Diags)
|
||||
{
|
||||
CompilerInvocation::CreateFromArgs(invocation, args->data() + 1,
|
||||
args->data() + args->size(),
|
||||
Diags);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ISL_CLANG_SYSROOT
|
||||
/* Set sysroot if required.
|
||||
*
|
||||
* If ISL_CLANG_SYSROOT is defined, then set it to this value.
|
||||
*/
|
||||
static void set_sysroot(ArgStringList &args)
|
||||
{
|
||||
args.push_back("-isysroot");
|
||||
args.push_back(ISL_CLANG_SYSROOT);
|
||||
}
|
||||
#else
|
||||
/* Set sysroot if required.
|
||||
*
|
||||
* If ISL_CLANG_SYSROOT is not defined, then it does not need to be set.
|
||||
*/
|
||||
static void set_sysroot(ArgStringList &args)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create a CompilerInvocation object that stores the command line
|
||||
* arguments constructed by the driver.
|
||||
* The arguments are mainly useful for setting up the system include
|
||||
* paths on newer clangs and on some platforms.
|
||||
*/
|
||||
static void construct_invocation(CompilerInstance *Clang,
|
||||
const char *filename, DiagnosticsEngine &Diags)
|
||||
{
|
||||
const char *binary = ISL_CLANG_PREFIX"/bin/clang";
|
||||
const std::unique_ptr<Driver> driver(construct_driver(binary, Diags));
|
||||
std::vector<const char *> Argv;
|
||||
Argv.push_back(binary);
|
||||
Argv.push_back(filename);
|
||||
const std::unique_ptr<Compilation> compilation(
|
||||
driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
|
||||
JobList &Jobs = compilation->getJobs();
|
||||
|
||||
Command *cmd = cast<Command>(ClangAPI::command(*Jobs.begin()));
|
||||
if (strcmp(cmd->getCreator().getName(), "clang"))
|
||||
return;
|
||||
|
||||
ArgStringList args = cmd->getArguments();
|
||||
set_sysroot(args);
|
||||
|
||||
create_from_args(Clang->getInvocation(), &args, Diags);
|
||||
}
|
||||
|
||||
#ifdef CREATETARGETINFO_TAKES_SHARED_PTR
|
||||
|
||||
static TargetInfo *create_target_info(CompilerInstance *Clang,
|
||||
DiagnosticsEngine &Diags)
|
||||
{
|
||||
std::shared_ptr<TargetOptions> TO = Clang->getInvocation().TargetOpts;
|
||||
TO->Triple = llvm::sys::getDefaultTargetTriple();
|
||||
return TargetInfo::CreateTargetInfo(Diags, TO);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static TargetInfo *create_target_info(CompilerInstance *Clang,
|
||||
DiagnosticsEngine &Diags)
|
||||
{
|
||||
TargetOptions &TO = Clang->getTargetOpts();
|
||||
TO.Triple = llvm::sys::getDefaultTargetTriple();
|
||||
return TargetInfo::CreateTargetInfo(Diags, TO);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CREATEDIAGNOSTICS_TAKES_VFS
|
||||
|
||||
static void create_diagnostics(CompilerInstance *Clang)
|
||||
{
|
||||
Clang->createDiagnostics(*llvm::vfs::getRealFileSystem());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void create_diagnostics(CompilerInstance *Clang)
|
||||
{
|
||||
Clang->createDiagnostics();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void create_preprocessor(CompilerInstance *Clang)
|
||||
{
|
||||
Clang->createPreprocessor(TU_Complete);
|
||||
}
|
||||
|
||||
/* Add "Path" to the header search options.
|
||||
*
|
||||
* Do not take into account sysroot, i.e., set ignoreSysRoot to true.
|
||||
*/
|
||||
static void add_path(HeaderSearchOptions &HSO, std::string Path)
|
||||
{
|
||||
HSO.AddPath(Path, frontend::Angled, false, true);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void create_main_file_id(SourceManager &SM, const T &file)
|
||||
{
|
||||
SM.setMainFileID(SM.createFileID(file, SourceLocation(),
|
||||
SrcMgr::C_User));
|
||||
}
|
||||
|
||||
#ifdef SETLANGDEFAULTS_TAKES_5_ARGUMENTS
|
||||
|
||||
#include "isl-interface/set_lang_defaults_arg4.h"
|
||||
|
||||
static void set_lang_defaults(CompilerInstance *Clang)
|
||||
{
|
||||
PreprocessorOptions &PO = Clang->getPreprocessorOpts();
|
||||
TargetOptions &TO = Clang->getTargetOpts();
|
||||
llvm::Triple T(TO.Triple);
|
||||
SETLANGDEFAULTS::setLangDefaults(Clang->getLangOpts(), IK_C, T,
|
||||
setLangDefaultsArg4(PO),
|
||||
LangStandard::lang_unspecified);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void set_lang_defaults(CompilerInstance *Clang)
|
||||
{
|
||||
CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
|
||||
LangStandard::lang_unspecified);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Helper function for ignore_error that only gets enabled if T
|
||||
* (which is either const FileEntry * or llvm::ErrorOr<const FileEntry *>)
|
||||
* has getError method, i.e., if it is llvm::ErrorOr<const FileEntry *>.
|
||||
*/
|
||||
template <class T>
|
||||
static const FileEntry *ignore_error_helper(const T obj, int,
|
||||
int[1][sizeof(obj.getError())])
|
||||
{
|
||||
return *obj;
|
||||
}
|
||||
|
||||
/* Helper function for ignore_error that is always enabled,
|
||||
* but that only gets selected if the variant above is not enabled,
|
||||
* i.e., if T is const FileEntry *.
|
||||
*/
|
||||
template <class T>
|
||||
static const FileEntry *ignore_error_helper(const T obj, long, void *)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* Given either a const FileEntry * or a llvm::ErrorOr<const FileEntry *>,
|
||||
* extract out the const FileEntry *.
|
||||
*/
|
||||
template <class T>
|
||||
static const FileEntry *ignore_error(const T obj)
|
||||
{
|
||||
return ignore_error_helper(obj, 0, NULL);
|
||||
}
|
||||
|
||||
/* Define a template class "CLASS" with value true
|
||||
* if "EXPR" is valid for its template argument (available as "U" in "EXPR").
|
||||
*/
|
||||
#define ISL_VALID_EXPR_FOR_TEMPLATE_ARG(CLASS, EXPR) \
|
||||
template <typename T> \
|
||||
struct CLASS { \
|
||||
private: \
|
||||
template <typename U> \
|
||||
static auto test(int) -> decltype(EXPR, std::true_type()); \
|
||||
\
|
||||
template <typename> \
|
||||
static std::false_type test(...); \
|
||||
\
|
||||
public: \
|
||||
using type = decltype(test<T>(0)); \
|
||||
static constexpr bool value = type::value; \
|
||||
};
|
||||
|
||||
/* A template class with value true if the template argument
|
||||
* has a getFileRef method.
|
||||
*/
|
||||
ISL_VALID_EXPR_FOR_TEMPLATE_ARG(HasGetFileRef,
|
||||
std::declval<U>().getFileRef(std::declval<const std::string &>()))
|
||||
|
||||
/* Return a wrapper around the FileEntryRef/FileEntry
|
||||
* corresponding to the given file name. The wrapper evaluates
|
||||
* to false if an error occurs.
|
||||
*
|
||||
* If T (= FileManager) has a getFileRef method, then call that and
|
||||
* return an llvm::Expected<clang::FileEntryRef>.
|
||||
* Otherwise, call getFile and return a FileEntry (pointer) embedded
|
||||
* in an llvm::ErrorOr.
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<HasGetFileRef<T>::value, bool>::type = true>
|
||||
static auto getFile(T& obj, const std::string &filename)
|
||||
-> decltype(obj.getFileRef(filename))
|
||||
{
|
||||
return obj.getFileRef(filename);
|
||||
}
|
||||
template <typename T,
|
||||
typename std::enable_if<!HasGetFileRef<T>::value, bool>::type = true>
|
||||
static llvm::ErrorOr<const FileEntry *> getFile(T& obj,
|
||||
const std::string &filename)
|
||||
{
|
||||
const FileEntry *file = ignore_error(obj.getFile(filename));
|
||||
if (!file)
|
||||
return std::error_code();
|
||||
return file;
|
||||
}
|
||||
|
||||
/* A template class with value true if the constructor of the template argument
|
||||
* takes a reference to a DiagnosticOptions object.
|
||||
*/
|
||||
ISL_VALID_EXPR_FOR_TEMPLATE_ARG(TakesDiagnosticOptionsRef,
|
||||
new U(llvm::errs(), std::declval<DiagnosticOptions &>()))
|
||||
|
||||
/* Return the type of the DiagnosticOptions argument of the constructor of "T".
|
||||
*
|
||||
* If TakesDiagnosticOptionsRef holds, then this is a reference
|
||||
* to a DiagnosticOptions object.
|
||||
* Otherwise, it is a pointer to such an object.
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<TakesDiagnosticOptionsRef<T>::value,
|
||||
bool>::type = true>
|
||||
static DiagnosticOptions &diag_opts_type();
|
||||
template <typename T,
|
||||
typename std::enable_if<!TakesDiagnosticOptionsRef<T>::value,
|
||||
bool>::type = true>
|
||||
static DiagnosticOptions *diag_opts_type();
|
||||
|
||||
/* A helper class handling the invocation of clang on a file and
|
||||
* allowing a derived class to perform the actual parsing
|
||||
* in an overridden handle() method.
|
||||
* Other virtual methods allow different kinds of configuration.
|
||||
*/
|
||||
struct Wrap {
|
||||
/* The type of the DiagnosticOptions argument
|
||||
* of the TextDiagnosticPrinter constructor.
|
||||
*/
|
||||
using DiagOptsType = decltype(diag_opts_type<TextDiagnosticPrinter>());
|
||||
/* A local DiagnosticOptions object that is used
|
||||
* if TextDiagnosticPrinter takes a reference
|
||||
* to a DiagnosticOptions object.
|
||||
*/
|
||||
DiagnosticOptions DiagOpts;
|
||||
|
||||
/* Return a valid DiagnosticOptions argument
|
||||
* for the constructor of "T".
|
||||
* If "T" takes a reference, then
|
||||
* this is a reference to the DiagOpts field.
|
||||
* Otherwise, it is a pointer to a new object.
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<TakesDiagnosticOptionsRef<T>::value,
|
||||
bool>::type = true>
|
||||
DiagnosticOptions &getDiagOpts() {
|
||||
return DiagOpts;
|
||||
}
|
||||
template <typename T,
|
||||
typename std::enable_if<!TakesDiagnosticOptionsRef<T>::value,
|
||||
bool>::type = true>
|
||||
DiagnosticOptions *getDiagOpts() {
|
||||
return new DiagnosticOptions();
|
||||
}
|
||||
|
||||
/* Return a valid DiagnosticOptions argument for
|
||||
* the TextDiagnosticPrinter constructor.
|
||||
* If TextDiagnosticPrinter takes a reference, then
|
||||
* this is a reference to the DiagOpts field.
|
||||
* Otherwise, it is a pointer to a new object.
|
||||
*/
|
||||
DiagOptsType getDiagnosticOptions() {
|
||||
return getDiagOpts<TextDiagnosticPrinter>();
|
||||
}
|
||||
|
||||
/* Construct a TextDiagnosticPrinter. */
|
||||
virtual TextDiagnosticPrinter *construct_printer() = 0;
|
||||
/* Suppress any errors, if needed. */
|
||||
virtual void suppress_errors(DiagnosticsEngine &Diags) = 0;
|
||||
/* Add required search paths to "HSO". */
|
||||
virtual void add_paths(HeaderSearchOptions &HSO) = 0;
|
||||
/* Add required macro definitions to "PO". */
|
||||
virtual void add_macros(PreprocessorOptions &PO) = 0;
|
||||
/* Handle an error opening the file. */
|
||||
virtual void handle_error() = 0;
|
||||
/* Parse the file, returning true if no error was encountered. */
|
||||
virtual bool handle(CompilerInstance *Clang) = 0;
|
||||
|
||||
/* Invoke clang on "filename", passing control to the handle() method
|
||||
* for parsing.
|
||||
*/
|
||||
bool invoke(const char *filename) {
|
||||
CompilerInstance *Clang = new CompilerInstance();
|
||||
create_diagnostics(Clang);
|
||||
DiagnosticsEngine &Diags = Clang->getDiagnostics();
|
||||
Diags.setSuppressSystemWarnings(true);
|
||||
suppress_errors(Diags);
|
||||
TargetInfo *target = create_target_info(Clang, Diags);
|
||||
Clang->setTarget(target);
|
||||
set_lang_defaults(Clang);
|
||||
construct_invocation(Clang, filename, Diags);
|
||||
Diags.setClient(construct_printer());
|
||||
Clang->createFileManager();
|
||||
Clang->createSourceManager(Clang->getFileManager());
|
||||
HeaderSearchOptions &HSO = Clang->getHeaderSearchOpts();
|
||||
LangOptions &LO = Clang->getLangOpts();
|
||||
PreprocessorOptions &PO = Clang->getPreprocessorOpts();
|
||||
HSO.ResourceDir = ResourceDir;
|
||||
HSO.AddPath(ISL_CLANG_RESOURCE_DIR "/include",
|
||||
clang::frontend::System, false, false);
|
||||
|
||||
add_paths(HSO);
|
||||
add_macros(PO);
|
||||
|
||||
create_preprocessor(Clang);
|
||||
Preprocessor &PP = Clang->getPreprocessor();
|
||||
|
||||
PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
|
||||
LO);
|
||||
auto file = getFile(Clang->getFileManager(), filename);
|
||||
if (!file) {
|
||||
handle_error();
|
||||
delete Clang;
|
||||
return false;
|
||||
}
|
||||
create_main_file_id(Clang->getSourceManager(), *file);
|
||||
|
||||
Clang->createASTContext();
|
||||
bool ok = handle(Clang);
|
||||
delete Clang;
|
||||
|
||||
return ok;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
16
polly/lib/External/isl/interface/include/isl-interface/config.h.in
vendored
Normal file
16
polly/lib/External/isl/interface/include/isl-interface/config.h.in
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef ISL_CLANG_WRAP_CONFIG_H
|
||||
#define ISL_CLANG_WRAP_CONFIG_H
|
||||
|
||||
#undef CREATE_FROM_ARGS_TAKES_ARRAYREF
|
||||
#undef CREATEDIAGNOSTICS_TAKES_VFS
|
||||
#undef CREATETARGETINFO_TAKES_SHARED_PTR
|
||||
#undef HAVE_LLVM_OPTION_ARG_H
|
||||
#undef HAVE_TARGETPARSER_HOST_H
|
||||
#undef IK_C
|
||||
#undef ISL_CLANG_PREFIX
|
||||
#undef ISL_CLANG_RESOURCE_DIR
|
||||
#undef ISL_CLANG_SYSROOT
|
||||
#undef SETLANGDEFAULTS
|
||||
#undef SETLANGDEFAULTS_TAKES_5_ARGUMENTS
|
||||
|
||||
#endif
|
||||
34
polly/lib/External/isl/interface/isl.py.core
vendored
34
polly/lib/External/isl/interface/isl.py.core
vendored
@ -12850,6 +12850,22 @@ class fixed_box(object):
|
||||
return obj
|
||||
def get_offset(arg0):
|
||||
return arg0.offset()
|
||||
def plain_is_equal(arg0, arg1):
|
||||
try:
|
||||
if not arg0.__class__ is fixed_box:
|
||||
arg0 = fixed_box(arg0)
|
||||
except:
|
||||
raise
|
||||
try:
|
||||
if not arg1.__class__ is fixed_box:
|
||||
arg1 = fixed_box(arg1)
|
||||
except:
|
||||
raise
|
||||
ctx = arg0.ctx
|
||||
res = isl.isl_fixed_box_plain_is_equal(arg0.ptr, arg1.ptr)
|
||||
if res < 0:
|
||||
raise Error
|
||||
return bool(res)
|
||||
def size(arg0):
|
||||
try:
|
||||
if not arg0.__class__ is fixed_box:
|
||||
@ -12880,6 +12896,7 @@ isl.isl_fixed_box_read_from_str.argtypes = [Context, c_char_p]
|
||||
isl.isl_fixed_box_is_valid.argtypes = [c_void_p]
|
||||
isl.isl_fixed_box_get_offset.restype = c_void_p
|
||||
isl.isl_fixed_box_get_offset.argtypes = [c_void_p]
|
||||
isl.isl_fixed_box_plain_is_equal.argtypes = [c_void_p, c_void_p]
|
||||
isl.isl_fixed_box_get_size.restype = c_void_p
|
||||
isl.isl_fixed_box_get_size.argtypes = [c_void_p]
|
||||
isl.isl_fixed_box_get_space.restype = c_void_p
|
||||
@ -13889,6 +13906,22 @@ class multi_val(object):
|
||||
if res < 0:
|
||||
raise Error
|
||||
return bool(res)
|
||||
def is_equal(arg0, arg1):
|
||||
try:
|
||||
if not arg0.__class__ is multi_val:
|
||||
arg0 = multi_val(arg0)
|
||||
except:
|
||||
raise
|
||||
try:
|
||||
if not arg1.__class__ is multi_val:
|
||||
arg1 = multi_val(arg1)
|
||||
except:
|
||||
raise
|
||||
ctx = arg0.ctx
|
||||
res = isl.isl_multi_val_is_equal(arg0.ptr, arg1.ptr)
|
||||
if res < 0:
|
||||
raise Error
|
||||
return bool(res)
|
||||
def list(arg0):
|
||||
try:
|
||||
if not arg0.__class__ is multi_val:
|
||||
@ -14164,6 +14197,7 @@ isl.isl_multi_val_flat_range_product.restype = c_void_p
|
||||
isl.isl_multi_val_flat_range_product.argtypes = [c_void_p, c_void_p]
|
||||
isl.isl_multi_val_has_range_tuple_id.argtypes = [c_void_p]
|
||||
isl.isl_multi_val_involves_nan.argtypes = [c_void_p]
|
||||
isl.isl_multi_val_is_equal.argtypes = [c_void_p, c_void_p]
|
||||
isl.isl_multi_val_get_list.restype = c_void_p
|
||||
isl.isl_multi_val_get_list.argtypes = [c_void_p]
|
||||
isl.isl_multi_val_max.restype = c_void_p
|
||||
|
||||
@ -1936,7 +1936,7 @@ void plain_cpp_generator::impl_printer::print_callback_body(int indent,
|
||||
|
||||
callback = extract_prototype(ptype);
|
||||
rtype = callback->getReturnType();
|
||||
num_params = callback->getNumArgs();
|
||||
num_params = callback->getNumParams();
|
||||
|
||||
last_idx = ::to_string(num_params - 1);
|
||||
|
||||
|
||||
8
polly/lib/External/isl/interface/python.cc
vendored
8
polly/lib/External/isl/interface/python.cc
vendored
@ -215,7 +215,7 @@ void python_generator::print_callback(ParmVarDecl *param, int arg)
|
||||
QualType type = param->getOriginalType();
|
||||
const FunctionProtoType *fn = extract_prototype(type);
|
||||
QualType return_type = fn->getReturnType();
|
||||
unsigned n_arg = fn->getNumArgs();
|
||||
unsigned n_arg = fn->getNumParams();
|
||||
|
||||
printf(" exc_info = [None]\n");
|
||||
printf(" fn = CFUNCTYPE(");
|
||||
@ -224,7 +224,7 @@ void python_generator::print_callback(ParmVarDecl *param, int arg)
|
||||
else
|
||||
printf("c_void_p");
|
||||
for (unsigned i = 0; i < n_arg - 1; ++i) {
|
||||
if (!is_isl_type(fn->getArgType(i)))
|
||||
if (!is_isl_type(fn->getParamType(i)))
|
||||
die("Argument has non-isl type");
|
||||
printf(", c_void_p");
|
||||
}
|
||||
@ -238,11 +238,11 @@ void python_generator::print_callback(ParmVarDecl *param, int arg)
|
||||
printf("):\n");
|
||||
for (unsigned i = 0; i < n_arg - 1; ++i) {
|
||||
string arg_type;
|
||||
arg_type = type2python(extract_type(fn->getArgType(i)));
|
||||
arg_type = type2python(extract_type(fn->getParamType(i)));
|
||||
printf(" cb_arg%d = %s(ctx=arg0.ctx, ptr=",
|
||||
i, arg_type.c_str());
|
||||
if (!callback_takes_argument(param, i))
|
||||
print_copy(fn->getArgType(i));
|
||||
print_copy(fn->getParamType(i));
|
||||
printf("(cb_arg%d))\n", i);
|
||||
}
|
||||
printf(" try:\n");
|
||||
|
||||
@ -1647,7 +1647,7 @@ static int total_params(const Method &method)
|
||||
auto callback_type = callback->getType();
|
||||
auto proto = generator::extract_prototype(callback_type);
|
||||
|
||||
n += proto->getNumArgs() - 1;
|
||||
n += proto->getNumParams() - 1;
|
||||
n -= 1;
|
||||
}
|
||||
|
||||
@ -1729,10 +1729,10 @@ static void print_callback_args(std::ostream &os,
|
||||
const std::function<void(const std::string &type,
|
||||
const std::string &name)> &print_arg)
|
||||
{
|
||||
auto n_arg = callback->getNumArgs() - 1;
|
||||
auto n_arg = callback->getNumParams() - 1;
|
||||
|
||||
Method::print_arg_list(os, 0, n_arg, [&] (int i) {
|
||||
auto type = callback->getArgType(i);
|
||||
auto type = callback->getParamType(i);
|
||||
auto name = "arg" + std::to_string(i);
|
||||
auto cpptype = type_printer.param(shift + i, type);
|
||||
|
||||
@ -2709,7 +2709,7 @@ const std::string callback_name(const Method &method)
|
||||
|
||||
auto type = method.callbacks.at(0)->getType();
|
||||
auto callback = cpp_generator::extract_prototype(type);
|
||||
auto arg_type = plain_type(callback->getArgType(0));
|
||||
auto arg_type = plain_type(callback->getParamType(0));
|
||||
return generator::drop_suffix(method.name, "_" + arg_type);
|
||||
}
|
||||
|
||||
|
||||
28
polly/lib/External/isl/isl_arg.c
vendored
28
polly/lib/External/isl/isl_arg.c
vendored
@ -974,19 +974,25 @@ static int parse_str_option(struct isl_arg *decl, char **arg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int isl_arg_str_list_append(struct isl_arg *decl, void *opt,
|
||||
int isl_arg_str_list_append(int *n, const char ***list, const char *s)
|
||||
{
|
||||
const char **new_list;
|
||||
|
||||
new_list = realloc(*list, (*n + 1) * sizeof(char *));
|
||||
if (!new_list)
|
||||
return -1;
|
||||
*list = new_list;
|
||||
new_list[*n] = strdup(s);
|
||||
return isl_stat_non_null(new_list[(*n)++]);
|
||||
}
|
||||
|
||||
static int arg_str_list_append(struct isl_arg *decl, void *opt,
|
||||
const char *s)
|
||||
{
|
||||
int *n = (int *)(((char *) opt) + decl->u.str_list.offset_n);
|
||||
char **list = *(char ***)(((char *) opt) + decl->offset);
|
||||
const char ***list = (const char ***)(((char *) opt) + decl->offset);
|
||||
|
||||
list = realloc(list, (*n + 1) * sizeof(char *));
|
||||
if (!list)
|
||||
return -1;
|
||||
*(char ***)(((char *) opt) + decl->offset) = list;
|
||||
list[*n] = strdup(s);
|
||||
(*n)++;
|
||||
return 0;
|
||||
return isl_arg_str_list_append(n, list, s);
|
||||
}
|
||||
|
||||
static int parse_str_list_option(struct isl_arg *decl, char **arg,
|
||||
@ -1000,12 +1006,12 @@ static int parse_str_list_option(struct isl_arg *decl, char **arg,
|
||||
return 0;
|
||||
|
||||
if (has_argument) {
|
||||
isl_arg_str_list_append(decl, opt, s);
|
||||
arg_str_list_append(decl, opt, s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (arg[1]) {
|
||||
isl_arg_str_list_append(decl, opt, arg[1]);
|
||||
arg_str_list_append(decl, opt, arg[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
229
polly/lib/External/isl/isl_box.c
vendored
229
polly/lib/External/isl/isl_box.c
vendored
@ -207,27 +207,65 @@ isl_bool isl_fixed_box_is_valid(__isl_keep isl_fixed_box *box)
|
||||
|
||||
/* Return the offsets of the box "box".
|
||||
*/
|
||||
__isl_give isl_multi_aff *isl_fixed_box_get_offset(
|
||||
static __isl_keep isl_multi_aff *isl_fixed_box_peek_offset(
|
||||
__isl_keep isl_fixed_box *box)
|
||||
{
|
||||
if (!box)
|
||||
return NULL;
|
||||
return isl_multi_aff_copy(box->offset);
|
||||
return box->offset;
|
||||
}
|
||||
|
||||
/* Return a copy of the offsets of the box "box".
|
||||
*/
|
||||
__isl_give isl_multi_aff *isl_fixed_box_get_offset(
|
||||
__isl_keep isl_fixed_box *box)
|
||||
{
|
||||
return isl_multi_aff_copy(isl_fixed_box_peek_offset(box));
|
||||
}
|
||||
|
||||
/* Return the sizes of the box "box".
|
||||
*/
|
||||
__isl_give isl_multi_val *isl_fixed_box_get_size(__isl_keep isl_fixed_box *box)
|
||||
static __isl_keep isl_multi_val *isl_fixed_box_peek_size(
|
||||
__isl_keep isl_fixed_box *box)
|
||||
{
|
||||
if (!box)
|
||||
return NULL;
|
||||
return isl_multi_val_copy(box->size);
|
||||
return box->size;
|
||||
}
|
||||
|
||||
/* Return a copy of the sizes of the box "box".
|
||||
*/
|
||||
__isl_give isl_multi_val *isl_fixed_box_get_size(__isl_keep isl_fixed_box *box)
|
||||
{
|
||||
return isl_multi_val_copy(isl_fixed_box_peek_size(box));
|
||||
}
|
||||
|
||||
/* Is "box1" obviously equal to "box2"?
|
||||
*
|
||||
* That is, does it have the same size and obviously the same offset?
|
||||
*/
|
||||
isl_bool isl_fixed_box_plain_is_equal(__isl_keep isl_fixed_box *box1,
|
||||
__isl_keep isl_fixed_box *box2)
|
||||
{
|
||||
isl_multi_aff *offset1, *offset2;
|
||||
isl_multi_val *size1, *size2;
|
||||
isl_bool equal;
|
||||
|
||||
size1 = isl_fixed_box_peek_size(box1);
|
||||
size2 = isl_fixed_box_peek_size(box2);
|
||||
equal = isl_multi_val_is_equal(size1, size2);
|
||||
if (equal < 0 || !equal)
|
||||
return equal;
|
||||
|
||||
offset1 = isl_fixed_box_peek_offset(box1);
|
||||
offset2 = isl_fixed_box_peek_offset(box2);
|
||||
return isl_multi_aff_plain_is_equal(offset1, offset2);
|
||||
}
|
||||
|
||||
/* Data used in set_dim_extent and compute_size_in_direction.
|
||||
*
|
||||
* "bset" is a wrapped copy of the basic map that has the selected
|
||||
* output dimension as range.
|
||||
* output dimension as range, without any contraction.
|
||||
* "pos" is the position of the variable representing the output dimension,
|
||||
* i.e., the variable for which the size should be computed. This variable
|
||||
* is also the last variable in "bset".
|
||||
@ -235,34 +273,167 @@ __isl_give isl_multi_val *isl_fixed_box_get_size(__isl_keep isl_fixed_box *box)
|
||||
* (infinity if no offset was found so far).
|
||||
* "offset" is the offset corresponding to the best size
|
||||
* (NULL if no offset was found so far).
|
||||
*
|
||||
* If "expand" is not NULL, then it maps a contracted version of "bset"
|
||||
* to the original "bset", while "domain_map" maps the space of "bset"
|
||||
* to the domain of the wrapped map.
|
||||
*/
|
||||
struct isl_size_info {
|
||||
isl_basic_set *bset;
|
||||
isl_size pos;
|
||||
isl_val *size;
|
||||
isl_aff *offset;
|
||||
|
||||
isl_multi_aff *expand;
|
||||
isl_multi_aff *domain_map;
|
||||
};
|
||||
|
||||
/* Detect any stride in the single output dimension of "map" and
|
||||
* set the fields of "info" used in exploiting this stride.
|
||||
* If no (non-trivial) stride can be found, then set those fields to NULL.
|
||||
*
|
||||
* If there is a non-trivial stride, then the single output dimension i
|
||||
* is of the form
|
||||
*
|
||||
* i = offset + stride * i'
|
||||
*
|
||||
* Construct a function that maps i' to i.
|
||||
* Note that the offset may depend on the domain of the map,
|
||||
* so it needs to be of the form
|
||||
*
|
||||
* [D -> [i']] -> [i]
|
||||
*
|
||||
* In fact, it is more convenient for the function to be of the form
|
||||
*
|
||||
* [D -> [i']] -> [D -> [i]]
|
||||
*
|
||||
* First construct helper functions
|
||||
*
|
||||
* [D -> [i]] -> D
|
||||
* [D -> [i]] -> [i]
|
||||
*
|
||||
* Plug in [D -> [i]] -> D into the offset (defined on D) to obtain
|
||||
* the offset defined on [D -> [i]] and add stride times [D -> [i]] -> [i].
|
||||
* This produces the function
|
||||
*
|
||||
* [D -> [i']] = [offset + stride i']
|
||||
*
|
||||
* Combine it with [D -> [i]] -> D again to obtain the desired result.
|
||||
*/
|
||||
static __isl_give isl_map *isl_size_info_detect_stride(
|
||||
struct isl_size_info *info, __isl_take isl_map *map)
|
||||
{
|
||||
isl_stride_info *si;
|
||||
isl_val *stride;
|
||||
isl_aff *offset;
|
||||
isl_bool is_one;
|
||||
isl_multi_aff *domain_map, *id;
|
||||
isl_multi_aff *expand;
|
||||
|
||||
info->expand = NULL;
|
||||
info->domain_map = NULL;
|
||||
|
||||
si = isl_map_get_range_stride_info(map, 0);
|
||||
stride = isl_stride_info_get_stride(si);
|
||||
is_one = isl_val_is_one(stride);
|
||||
if (is_one < 0 || is_one) {
|
||||
isl_val_free(stride);
|
||||
isl_stride_info_free(si);
|
||||
return is_one < 0 ? isl_map_free(map) : map;
|
||||
}
|
||||
offset = isl_stride_info_get_offset(si);
|
||||
isl_stride_info_free(si);
|
||||
|
||||
domain_map = isl_space_domain_map_multi_aff(isl_aff_get_space(offset));
|
||||
id = isl_space_range_map_multi_aff(isl_aff_get_space(offset));
|
||||
offset = isl_aff_pullback_multi_aff(offset,
|
||||
isl_multi_aff_copy(domain_map));
|
||||
|
||||
expand = isl_multi_aff_scale_val(id, stride);
|
||||
expand = isl_multi_aff_add(expand, isl_multi_aff_from_aff(offset));
|
||||
expand = isl_multi_aff_range_product(isl_multi_aff_copy(domain_map),
|
||||
expand);
|
||||
info->expand = expand;
|
||||
info->domain_map = domain_map;
|
||||
|
||||
if (!expand || !domain_map)
|
||||
return isl_map_free(map);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/* If any stride was detected in the single output dimension
|
||||
* in the wrapped map in "bset" (i.e., if info->expand is set),
|
||||
* then plug in the expansion to obtain a description in terms
|
||||
* of an output dimension without stride.
|
||||
* Otherwise, return the original "bset".
|
||||
*/
|
||||
static __isl_give isl_basic_set *isl_size_info_contract(
|
||||
struct isl_size_info *info, __isl_take isl_basic_set *bset)
|
||||
{
|
||||
if (!info->expand)
|
||||
return bset;
|
||||
|
||||
bset = isl_basic_set_preimage_multi_aff(bset,
|
||||
isl_multi_aff_copy(info->expand));
|
||||
|
||||
return bset;
|
||||
}
|
||||
|
||||
/* Given an affine function "aff" that maps the space of "bset"
|
||||
* to a value in the (possibly) contracted space,
|
||||
* expand it back to the original space.
|
||||
* The value of "aff" only depends on the domain of wrapped relation
|
||||
* inside "bset".
|
||||
*
|
||||
* If info->expand is not set, then no contraction was applied and
|
||||
* "aff" is returned.
|
||||
*
|
||||
* Otherwise, combine "aff" of the form [D -> [*]] -> [v'(D)]
|
||||
* with [D -> [*]] -> D to obtain [D -> [*]] -> [D -> [v'(D)]].
|
||||
* Apply the expansion [D -> [i']] = [D -> [offset + stride * i']]
|
||||
* to obtain [D -> [*]] -> [D -> [offset + stride * v'(D)]] and
|
||||
* extract out [D -> [*]] -> [offset + stride * v'(D)].
|
||||
*/
|
||||
static __isl_give isl_aff *isl_size_info_expand(
|
||||
struct isl_size_info *info, __isl_take isl_aff *aff)
|
||||
{
|
||||
isl_multi_aff *ma;
|
||||
|
||||
if (!info->expand)
|
||||
return aff;
|
||||
|
||||
ma = isl_multi_aff_from_aff(aff);
|
||||
ma = isl_multi_aff_range_product(isl_multi_aff_copy(info->domain_map),
|
||||
ma);
|
||||
ma = isl_multi_aff_pullback_multi_aff(isl_multi_aff_copy(info->expand),
|
||||
ma);
|
||||
ma = isl_multi_aff_range_factor_range(ma);
|
||||
aff = isl_multi_aff_get_at(ma, 0);
|
||||
isl_multi_aff_free(ma);
|
||||
|
||||
return aff;
|
||||
}
|
||||
|
||||
/* Free all memory allocated for "info".
|
||||
*/
|
||||
static void isl_size_info_clear(struct isl_size_info *info)
|
||||
{
|
||||
isl_val_free(info->size);
|
||||
isl_aff_free(info->offset);
|
||||
isl_basic_set_free(info->bset);
|
||||
|
||||
isl_multi_aff_free(info->expand);
|
||||
isl_multi_aff_free(info->domain_map);
|
||||
}
|
||||
|
||||
/* Is "c" a suitable bound on dimension "pos" for use as a lower bound
|
||||
* of a fixed-size range.
|
||||
* In particular, it needs to be a lower bound on "pos".
|
||||
* In order for the final offset not to be too complicated,
|
||||
* the constraint itself should also not involve any integer divisions.
|
||||
*/
|
||||
static isl_bool is_suitable_bound(__isl_keep isl_constraint *c, unsigned pos)
|
||||
{
|
||||
isl_size n_div;
|
||||
isl_bool is_bound, any_divs;
|
||||
|
||||
is_bound = isl_constraint_is_lower_bound(c, isl_dim_set, pos);
|
||||
if (is_bound < 0 || !is_bound)
|
||||
return is_bound;
|
||||
|
||||
n_div = isl_constraint_dim(c, isl_dim_div);
|
||||
if (n_div < 0)
|
||||
return isl_bool_error;
|
||||
any_divs = isl_constraint_involves_dims(c, isl_dim_div, 0, n_div);
|
||||
return isl_bool_not(any_divs);
|
||||
return isl_constraint_is_lower_bound(c, isl_dim_set, pos);
|
||||
}
|
||||
|
||||
/* Given a constraint from the basic set describing the bounds on
|
||||
@ -271,6 +442,10 @@ static isl_bool is_suitable_bound(__isl_keep isl_constraint *c, unsigned pos)
|
||||
* upper bound. If so, and if this bound is smaller than any bound
|
||||
* derived from earlier constraints, set the size to this bound on
|
||||
* the expression and the lower bound to ceil(b(x)/m).
|
||||
*
|
||||
* If any contraction was applied, then the lower bound ceil(b(x)/m)
|
||||
* is defined in the contracted space, so it needs to be expanded
|
||||
* first before applying it to the original space.
|
||||
*/
|
||||
static isl_stat compute_size_in_direction(__isl_take isl_constraint *c,
|
||||
void *user)
|
||||
@ -289,6 +464,7 @@ static isl_stat compute_size_in_direction(__isl_take isl_constraint *c,
|
||||
|
||||
aff = isl_constraint_get_bound(c, isl_dim_set, info->pos);
|
||||
aff = isl_aff_ceil(aff);
|
||||
aff = isl_size_info_expand(info, aff);
|
||||
|
||||
lb = isl_aff_copy(aff);
|
||||
|
||||
@ -326,10 +502,17 @@ static isl_stat compute_size_in_direction(__isl_take isl_constraint *c,
|
||||
* then invalidate the box. Otherwise, set the offset and size
|
||||
* in the given direction by those that correspond to the smallest size.
|
||||
*
|
||||
* If the output dimension is strided, then scale it down before
|
||||
* looking for lower bounds. The size computation is however performed
|
||||
* in the original space.
|
||||
*
|
||||
* Note that while evaluating the size corresponding to a lower bound,
|
||||
* an affine expression is constructed from the lower bound.
|
||||
* This lower bound may therefore not have any unknown local variables.
|
||||
* Eliminate any unknown local variables up front.
|
||||
* Furthermore, the lower bound can clearly not involve
|
||||
* (any local variables that involve) the output dimension itself,
|
||||
* so any such local variables are eliminated as well.
|
||||
* No such restriction needs to be imposed on the set over which
|
||||
* the size is computed.
|
||||
*/
|
||||
@ -347,14 +530,18 @@ static __isl_give isl_fixed_box *set_dim_extent(__isl_take isl_fixed_box *box,
|
||||
ctx = isl_map_get_ctx(map);
|
||||
map = isl_map_copy(map);
|
||||
map = isl_map_project_onto(map, isl_dim_out, pos, 1);
|
||||
map = isl_size_info_detect_stride(&info, map);
|
||||
info.size = isl_val_infty(ctx);
|
||||
info.offset = NULL;
|
||||
info.pos = isl_map_dim(map, isl_dim_in);
|
||||
info.bset = isl_basic_map_wrap(isl_map_simple_hull(map));
|
||||
bset = isl_basic_set_copy(info.bset);
|
||||
bset = isl_size_info_contract(&info, bset);
|
||||
bset = isl_basic_set_remove_unknown_divs(bset);
|
||||
if (info.pos < 0)
|
||||
bset = isl_basic_set_free(bset);
|
||||
bset = isl_basic_set_remove_divs_involving_dims(bset, isl_dim_set,
|
||||
info.pos, 1);
|
||||
if (isl_basic_set_foreach_constraint(bset,
|
||||
&compute_size_in_direction, &info) < 0)
|
||||
box = isl_fixed_box_free(box);
|
||||
@ -367,9 +554,7 @@ static __isl_give isl_fixed_box *set_dim_extent(__isl_take isl_fixed_box *box,
|
||||
info.offset, info.size);
|
||||
else
|
||||
box = isl_fixed_box_invalidate(box);
|
||||
isl_val_free(info.size);
|
||||
isl_aff_free(info.offset);
|
||||
isl_basic_set_free(info.bset);
|
||||
isl_size_info_clear(&info);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
2
polly/lib/External/isl/isl_ctx.c
vendored
2
polly/lib/External/isl/isl_ctx.c
vendored
@ -31,7 +31,7 @@ isl_stat isl_stat_non_error_bool(isl_bool b)
|
||||
* That is, return isl_stat_ok if "obj" is non_NULL and
|
||||
* isl_stat_error otherwise.
|
||||
*/
|
||||
isl_stat isl_stat_non_null(void *obj)
|
||||
isl_stat isl_stat_non_null(const void *obj)
|
||||
{
|
||||
if (obj != NULL)
|
||||
return isl_stat_ok;
|
||||
|
||||
567
polly/lib/External/isl/isl_map_simplify.c
vendored
567
polly/lib/External/isl/isl_map_simplify.c
vendored
@ -71,6 +71,17 @@ static void swap_inequality(__isl_keep isl_basic_map *bmap, int a, int b)
|
||||
}
|
||||
}
|
||||
|
||||
/* Scale down the inequality constraint "ineq" of length "len"
|
||||
* by a factor of "f".
|
||||
* All the coefficients, except the constant term,
|
||||
* are assumed to be multiples of "f".
|
||||
*/
|
||||
static void scale_down_inequality(isl_int *ineq, isl_int f, unsigned len)
|
||||
{
|
||||
isl_int_fdiv_q(ineq[0], ineq[0], f);
|
||||
isl_seq_scale_down(ineq + 1, ineq + 1, f, len);
|
||||
}
|
||||
|
||||
/* Scale down the inequality constraint "ineq" of length "len"
|
||||
* by a factor of "f".
|
||||
* All the coefficients, except the constant term,
|
||||
@ -81,7 +92,7 @@ static void swap_inequality(__isl_keep isl_basic_map *bmap, int a, int b)
|
||||
* If scaling is performed then take into account that the constraint
|
||||
* is modified (not simply based on an equality constraint).
|
||||
*/
|
||||
static __isl_give isl_basic_map *scale_down_inequality(
|
||||
static __isl_give isl_basic_map *scale_down_bmap_inequality(
|
||||
__isl_take isl_basic_map *bmap, int ineq, isl_int f, unsigned len)
|
||||
{
|
||||
if (!bmap)
|
||||
@ -90,8 +101,7 @@ static __isl_give isl_basic_map *scale_down_inequality(
|
||||
if (isl_int_is_zero(f) || isl_int_is_one(f))
|
||||
return bmap;
|
||||
|
||||
isl_int_fdiv_q(bmap->ineq[ineq][0], bmap->ineq[ineq][0], f);
|
||||
isl_seq_scale_down(bmap->ineq[ineq] + 1, bmap->ineq[ineq] + 1, f, len);
|
||||
scale_down_inequality(bmap->ineq[ineq], f, len);
|
||||
|
||||
bmap = isl_basic_map_modify_inequality(bmap, 0);
|
||||
|
||||
@ -144,7 +154,7 @@ __isl_give isl_basic_map *isl_basic_map_normalize_constraints(
|
||||
}
|
||||
if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
|
||||
isl_int_gcd(gcd, gcd, bmap->ineq[i][0]);
|
||||
bmap = scale_down_inequality(bmap, i, gcd, total);
|
||||
bmap = scale_down_bmap_inequality(bmap, i, gcd, total);
|
||||
if (!bmap)
|
||||
goto error;
|
||||
}
|
||||
@ -399,7 +409,7 @@ static __isl_give isl_basic_map *eliminate_var_using_equality(
|
||||
mark_progress(progress);
|
||||
isl_seq_elim(bmap->ineq[k], eq, 1+pos, 1+total, NULL);
|
||||
isl_seq_gcd(bmap->ineq[k], 1 + total, &ctx->normalize_gcd);
|
||||
bmap = scale_down_inequality(bmap, k, ctx->normalize_gcd,
|
||||
bmap = scale_down_bmap_inequality(bmap, k, ctx->normalize_gcd,
|
||||
total);
|
||||
bmap = isl_basic_map_modify_inequality(bmap, equivalent);
|
||||
if (!bmap)
|
||||
@ -886,6 +896,47 @@ static isl_bool constraint_index_is_redundant(struct isl_constraint_index *ci,
|
||||
return isl_int_ge(ineq[0], (*ci->index[h])[0]);
|
||||
}
|
||||
|
||||
/* Look for pairs of inequality constraints in "bmap"
|
||||
* that are opposite to each other apart from the constant term.
|
||||
* "ci" contains a hash table of the inequality constraints of "bmap".
|
||||
* Return an array of size equal to the number of inequality constraints
|
||||
* with as entries either
|
||||
* - zero, if the constraint has no opposite, or
|
||||
* - 1 + the position of the opposite constraint.
|
||||
*/
|
||||
static int *detect_opposites(struct isl_constraint_index *ci,
|
||||
__isl_keep isl_basic_map *bmap)
|
||||
{
|
||||
isl_size n_ineq;
|
||||
int k, l, h;
|
||||
isl_ctx *ctx;
|
||||
int *opposite;
|
||||
|
||||
n_ineq = isl_basic_map_n_inequality(bmap);
|
||||
if (n_ineq < 0)
|
||||
return NULL;
|
||||
ctx = isl_basic_map_get_ctx(bmap);
|
||||
opposite = isl_calloc_array(ctx, int, n_ineq);
|
||||
if (!opposite)
|
||||
return NULL;
|
||||
|
||||
for (k = 0; k < n_ineq - 1; ++k) {
|
||||
if (opposite[k])
|
||||
continue;
|
||||
isl_seq_neg(bmap->ineq[k] + 1, bmap->ineq[k] + 1, ci->total);
|
||||
h = hash_index(ci, bmap, k);
|
||||
isl_seq_neg(bmap->ineq[k] + 1, bmap->ineq[k] + 1, ci->total);
|
||||
if (!ci->index[h])
|
||||
continue;
|
||||
l = ci->index[h] - &bmap->ineq[0];
|
||||
|
||||
opposite[k] = 1 + l;
|
||||
opposite[l] = 1 + k;
|
||||
}
|
||||
|
||||
return opposite;
|
||||
}
|
||||
|
||||
/* If we can eliminate more than one div, then we need to make
|
||||
* sure we do it from last div to first div, in order not to
|
||||
* change the position of the other divs that still need to
|
||||
@ -1263,12 +1314,12 @@ error:
|
||||
}
|
||||
|
||||
static __isl_give isl_basic_map *set_div_from_lower_bound(
|
||||
__isl_take isl_basic_map *bmap, int div, int ineq)
|
||||
__isl_take isl_basic_map *bmap, int div, isl_int *ineq)
|
||||
{
|
||||
unsigned total = isl_basic_map_offset(bmap, isl_dim_div);
|
||||
|
||||
isl_seq_neg(bmap->div[div] + 1, bmap->ineq[ineq], total + bmap->n_div);
|
||||
isl_int_set(bmap->div[div][0], bmap->ineq[ineq][total + div]);
|
||||
isl_seq_neg(bmap->div[div] + 1, ineq, total + bmap->n_div);
|
||||
isl_int_set(bmap->div[div][0], ineq[total + div]);
|
||||
isl_int_add(bmap->div[div][1], bmap->div[div][1], bmap->div[div][0]);
|
||||
isl_int_sub_ui(bmap->div[div][1], bmap->div[div][1], 1);
|
||||
isl_int_set_si(bmap->div[div][1 + total + div], 0);
|
||||
@ -1283,36 +1334,43 @@ static __isl_give isl_basic_map *set_div_from_lower_bound(
|
||||
* terms of the unknown div.
|
||||
*/
|
||||
static isl_bool ok_to_set_div_from_bound(__isl_keep isl_basic_map *bmap,
|
||||
int div, int ineq)
|
||||
int div, isl_int *ineq)
|
||||
{
|
||||
int j;
|
||||
unsigned total = isl_basic_map_offset(bmap, isl_dim_div);
|
||||
isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
|
||||
isl_size n_div = isl_basic_map_dim(bmap, isl_dim_div);
|
||||
|
||||
if (v_div < 0 || n_div < 0)
|
||||
return isl_bool_error;
|
||||
|
||||
/* Not defined in terms of unknown divs */
|
||||
for (j = 0; j < bmap->n_div; ++j) {
|
||||
for (j = 0; j < n_div; ++j) {
|
||||
isl_bool unknown;
|
||||
|
||||
if (div == j)
|
||||
continue;
|
||||
if (isl_int_is_zero(bmap->ineq[ineq][total + j]))
|
||||
if (isl_int_is_zero(ineq[1 + v_div + j]))
|
||||
continue;
|
||||
if (isl_int_is_zero(bmap->div[j][0]))
|
||||
return isl_bool_false;
|
||||
unknown = isl_basic_map_div_is_marked_unknown(bmap, j);
|
||||
if (unknown < 0 || unknown)
|
||||
return isl_bool_not(unknown);
|
||||
}
|
||||
|
||||
/* No other div defined in terms of this one => avoid loops */
|
||||
for (j = 0; j < bmap->n_div; ++j) {
|
||||
for (j = 0; j < n_div; ++j) {
|
||||
if (div == j)
|
||||
continue;
|
||||
if (isl_int_is_zero(bmap->div[j][0]))
|
||||
continue;
|
||||
if (!isl_int_is_zero(bmap->div[j][1 + total + div]))
|
||||
if (!isl_int_is_zero(bmap->div[j][1 + 1 + v_div + div]))
|
||||
return isl_bool_false;
|
||||
}
|
||||
|
||||
return isl_bool_true;
|
||||
}
|
||||
|
||||
/* Would an expression for div "div" based on inequality "ineq" of "bmap"
|
||||
* be a better expression than the current one?
|
||||
/* Would an expression for div "div" based on inequality "ineq"
|
||||
* be a better expression than the current one in "bmap"?
|
||||
*
|
||||
* If we do not have any expression yet, then any expression would be better.
|
||||
* Otherwise we check if the last variable involved in the inequality
|
||||
@ -1320,28 +1378,52 @@ static isl_bool ok_to_set_div_from_bound(__isl_keep isl_basic_map *bmap,
|
||||
* than the last variable involved in the current div expression.
|
||||
*/
|
||||
static isl_bool better_div_constraint(__isl_keep isl_basic_map *bmap,
|
||||
int div, int ineq)
|
||||
int div, isl_int *ineq)
|
||||
{
|
||||
unsigned total = isl_basic_map_offset(bmap, isl_dim_div);
|
||||
isl_size n_div = isl_basic_map_dim(bmap, isl_dim_div);
|
||||
int last_div;
|
||||
int last_ineq;
|
||||
isl_bool unknown;
|
||||
|
||||
if (n_div < 0)
|
||||
return isl_bool_error;
|
||||
if (isl_int_is_zero(bmap->div[div][0]))
|
||||
return isl_bool_true;
|
||||
unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
|
||||
if (unknown < 0 || unknown)
|
||||
return unknown;
|
||||
|
||||
if (isl_seq_any_non_zero(bmap->ineq[ineq] + total + div + 1,
|
||||
n_div - (div + 1)))
|
||||
if (isl_seq_any_non_zero(ineq + total + div + 1, n_div - (div + 1)))
|
||||
return isl_bool_false;
|
||||
|
||||
last_ineq = isl_seq_last_non_zero(bmap->ineq[ineq], total + div);
|
||||
last_ineq = isl_seq_last_non_zero(ineq, total + div);
|
||||
last_div = isl_seq_last_non_zero(bmap->div[div] + 1, total + n_div);
|
||||
|
||||
return last_ineq < last_div;
|
||||
}
|
||||
|
||||
/* Given a lower bound "ineq" on local variable "div" of "bmap"
|
||||
* that could in theory be used to define an integer division expression,
|
||||
* do so if it is better than the current expression (if any) and
|
||||
* if there is no risk of introducing circular definitions.
|
||||
* Set *progress if anything is changed.
|
||||
*/
|
||||
static __isl_give isl_basic_map *set_div_from_lower_bound_if_better(
|
||||
__isl_take isl_basic_map *bmap, int div, isl_int *ineq, int *progress)
|
||||
{
|
||||
isl_bool set_div;
|
||||
|
||||
set_div = better_div_constraint(bmap, div, ineq);
|
||||
if (set_div >= 0 && set_div)
|
||||
set_div = ok_to_set_div_from_bound(bmap, div, ineq);
|
||||
if (set_div < 0)
|
||||
return isl_basic_map_free(bmap);
|
||||
if (!set_div)
|
||||
return bmap;
|
||||
bmap = set_div_from_lower_bound(bmap, div, ineq);
|
||||
mark_progress(progress);
|
||||
return bmap;
|
||||
}
|
||||
|
||||
/* Is the sequence of "len" coefficients "ineq" equal to "res"
|
||||
* plus some non-trivial coefficients that are all a multiple of some number
|
||||
* greater than "sum"?
|
||||
@ -1691,7 +1773,7 @@ static __isl_give isl_basic_map *check_for_residues(
|
||||
continue;
|
||||
|
||||
isl_seq_sub(bmap->ineq[i], bmap->ineq[c], 1 + total);
|
||||
bmap = scale_down_inequality(bmap, i, ctx->normalize_gcd,
|
||||
bmap = scale_down_bmap_inequality(bmap, i, ctx->normalize_gcd,
|
||||
total);
|
||||
if (!bmap)
|
||||
return NULL;
|
||||
@ -1701,6 +1783,260 @@ static __isl_give isl_basic_map *check_for_residues(
|
||||
return bmap;
|
||||
}
|
||||
|
||||
/* Given constraints of the form
|
||||
*
|
||||
* -n f + g + m n e + c1 >= 0 (l)
|
||||
* g + c3 >= 0 (i)
|
||||
* -g + c4 >= 0 (j)
|
||||
*
|
||||
* with e the local variable at position "div",
|
||||
* does the following condition hold?
|
||||
*
|
||||
* c3 + c4 + (c1 - c3) % n < m n
|
||||
*
|
||||
* "v_div" is the position of the first local variable.
|
||||
*/
|
||||
static int is_residue_div_pair(__isl_take isl_basic_map *bmap,
|
||||
int l, int div, unsigned v_div, int i, int j, isl_int n)
|
||||
{
|
||||
isl_int tmp;
|
||||
int ok;
|
||||
|
||||
isl_int_init(tmp);
|
||||
isl_int_sub(tmp, bmap->ineq[l][0], bmap->ineq[i][0]);
|
||||
isl_int_fdiv_r(tmp, tmp, n);
|
||||
isl_int_add(tmp, tmp, bmap->ineq[i][0]);
|
||||
isl_int_add(tmp, tmp, bmap->ineq[j][0]);
|
||||
ok = isl_int_lt(tmp, bmap->ineq[l][1 + v_div + div]);
|
||||
isl_int_clear(tmp);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Given a lower bound constraint at position "l" of "bmap"
|
||||
* on local variable "div" such that the sum of the constant terms
|
||||
* of this constraint and the corresponding upper bound is equal to "sum",
|
||||
* as well as a separate pair of opposite constraints "i" and "j"
|
||||
* such that the sum of their constant terms is smaller than
|
||||
* the coefficient of "div" in "l",
|
||||
* check if this pair can be used to derive a reduced expression
|
||||
* for the local variable.
|
||||
* "total" is the total number of variables.
|
||||
* "v_div" is the position of the first local variable.
|
||||
* Set *progress if anything is changed.
|
||||
*
|
||||
* In particular, let l be the constraint
|
||||
*
|
||||
* -n f + g + m n e + c1 >= 0
|
||||
*
|
||||
* The opposite constraint is
|
||||
*
|
||||
* n f - g - m n e + c2 >= 0
|
||||
*
|
||||
* with c1 + c2 equal to "sum".
|
||||
*
|
||||
* The constraints i and j are of the form
|
||||
*
|
||||
* h + c3 >= 0
|
||||
* -h + c4 >= 0
|
||||
*
|
||||
* with c3 + c4 < m n.
|
||||
* First check that h is equal to g for some n greater than "sum".
|
||||
* The constraints i and j are then of the form
|
||||
*
|
||||
* g + c3 >= 0
|
||||
* -g + c4 >= 0
|
||||
*
|
||||
* From constraint "l" and its opposite,
|
||||
*
|
||||
* g + m n e - c2 <= n f <= g + m n e + c1
|
||||
*
|
||||
* combined with the fact that c1 + c2 < n, the following expression
|
||||
* can be obtained:
|
||||
*
|
||||
* f = floor((g + m n e + c1)/n) = floor((g + c1)/n) + m e
|
||||
*
|
||||
* Replacing c1 with
|
||||
*
|
||||
* c1 = c3 + (c1 - c3) = c3 + n floor((c1 - c3)/n) + (c1 - c3) % n
|
||||
*
|
||||
* results in
|
||||
*
|
||||
* f = floor((g + c3 + (c1 - c3) % n)/n) + floor((c1 - c3)/n) + m e
|
||||
*
|
||||
* From the constraints i and j, together with c3 + c4 < m n,
|
||||
*
|
||||
* 0 <= g + c3 < m n
|
||||
*
|
||||
* Since (c1 - c3) % n is non-negative,
|
||||
*
|
||||
* 0 <= g + c3 + (c1 - c3) % n
|
||||
*
|
||||
* holds as well. However,
|
||||
*
|
||||
* g + c3 + (c1 - c3) % n < m n
|
||||
*
|
||||
* may not necessarily hold. It is however the case if
|
||||
*
|
||||
* c3 + c4 + (c1 - c3) % n < m n
|
||||
*
|
||||
* holds, which is checked in is_residue_div_pair.
|
||||
*
|
||||
* Given
|
||||
*
|
||||
* 0 <= g + c3 + (c1 - c3) % n < m n
|
||||
*
|
||||
* also
|
||||
*
|
||||
* 0 <= floor((g + c3 + (c1 - c3) % n) / n) < m
|
||||
*
|
||||
* holds.
|
||||
*
|
||||
* So,
|
||||
*
|
||||
* f = floor((g + c3 + (c1 - c3) % n)/n) + floor((c1 - c3)/n) + m e
|
||||
*
|
||||
* and
|
||||
*
|
||||
* 0 <= floor((g + c3 + (c1 - c3) % n) / n) < m
|
||||
*
|
||||
* This means
|
||||
*
|
||||
* f - floor((c1 - c3)/n)
|
||||
*
|
||||
* is equal to a multiple of m plus a value between 0 and m - 1.
|
||||
* That is,
|
||||
*
|
||||
* e = floor((f - floor((c1 - c3)/n))/m)
|
||||
*
|
||||
* Construct the inequality constraint
|
||||
*
|
||||
* -n f + m n e + c1 - c3 >= 0
|
||||
*
|
||||
* scale it down to
|
||||
*
|
||||
* -f + m e + floor((c1 - c3)/n) >= 0
|
||||
*
|
||||
* and add m - 1, to obtain
|
||||
*
|
||||
* -f + m e + floor((c1 - c3)/n) + m - 1 >= 0
|
||||
*
|
||||
* This constraint can then be used by set_div_from_lower_bound_if_better
|
||||
* to obtain
|
||||
*
|
||||
* e = floor((f - floor((c1 - c3)/n))/m)
|
||||
*
|
||||
* Adding m - 1 is needed to be able to reuse set_div_from_lower_bound,
|
||||
* which subtracts this amount from the constraint (by adding it
|
||||
* to the negated constraint).
|
||||
*/
|
||||
static __isl_give isl_basic_map *set_residue_div(__isl_take isl_basic_map *bmap,
|
||||
int l, isl_int sum, int div,
|
||||
unsigned v_div, unsigned total, int i, int j, int *progress)
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
isl_vec *v;
|
||||
|
||||
if (!bmap)
|
||||
return NULL;
|
||||
|
||||
ctx = isl_basic_map_get_ctx(bmap);
|
||||
if (!is_residue(bmap->ineq[i], bmap->ineq[l], sum, total,
|
||||
&ctx->normalize_gcd))
|
||||
return bmap;
|
||||
|
||||
if (!is_residue_div_pair(bmap, l, div, v_div, i, j, ctx->normalize_gcd))
|
||||
return bmap;
|
||||
|
||||
v = isl_vec_alloc(ctx, 1 + total);
|
||||
if (!v)
|
||||
return isl_basic_map_free(bmap);
|
||||
isl_seq_cpy(v->el, bmap->ineq[l], 1 + total);
|
||||
isl_seq_sub(v->el, bmap->ineq[i], 1 + total);
|
||||
scale_down_inequality(v->el, ctx->normalize_gcd, total);
|
||||
isl_int_add(v->el[0], v->el[0], v->el[1 + v_div + div]);
|
||||
isl_int_sub_ui(v->el[0], v->el[0], 1);
|
||||
bmap = set_div_from_lower_bound_if_better(bmap, div, v->el, progress);
|
||||
isl_vec_free(v);
|
||||
|
||||
return bmap;
|
||||
}
|
||||
|
||||
/* Given a lower bound constraint at position "l" of "bmap"
|
||||
* on local variable "div" such that the sum of the constant terms
|
||||
* of this constraint and the corresponding upper bound is equal to "sum",
|
||||
* check if some other pair of constraints can be found in "opposite"
|
||||
* that can be used to derive a reduced expression for the local variable.
|
||||
* "opposite" describes all pairs of opposite constraints.
|
||||
* It is an array of size equal to the number of inequality constraints
|
||||
* with as entries either
|
||||
* - zero, if the constraint has no opposite, or
|
||||
* - 1 + the position of the opposite constraint.
|
||||
* Set *progress if anything is changed.
|
||||
*
|
||||
* In particular, let l be the constraint
|
||||
*
|
||||
* -n f + g + m n e + c1 >= 0
|
||||
*
|
||||
* The opposite constraint is
|
||||
*
|
||||
* n f - g - m n e + c2 >= 0
|
||||
*
|
||||
* with c1 + c2 equal to "sum".
|
||||
*
|
||||
* Look for a pair of constraints
|
||||
*
|
||||
* g + c3 >= 0
|
||||
* -g + c4 >= 0
|
||||
*
|
||||
* with c3 + c4 < m n that can be used to obtain a reduced expression for e.
|
||||
* First look for any pair of constraints with constant terms
|
||||
* that satisfy c3 + c4 < m n and then check whether either of them
|
||||
* can be used in this way.
|
||||
*/
|
||||
static __isl_give isl_basic_map *check_for_residue_div(
|
||||
__isl_take isl_basic_map *bmap, int *opposite, int l, isl_int sum,
|
||||
int div, int *progress)
|
||||
{
|
||||
int i;
|
||||
isl_size n, v_div, total;
|
||||
isl_ctx *ctx;
|
||||
|
||||
v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
|
||||
total = isl_basic_map_dim(bmap, isl_dim_all);
|
||||
n = isl_basic_map_n_inequality(bmap);
|
||||
if (v_div < 0 || total < 0 || n < 0)
|
||||
return isl_basic_map_free(bmap);
|
||||
|
||||
ctx = isl_basic_map_get_ctx(bmap);
|
||||
for (i = 0; i < n; ++i) {
|
||||
int j;
|
||||
|
||||
if (i == l)
|
||||
continue;
|
||||
if (!opposite[i])
|
||||
continue;
|
||||
j = opposite[i] - 1;
|
||||
if (j < i)
|
||||
continue;
|
||||
if (j == l)
|
||||
continue;
|
||||
if (!isl_int_is_zero(bmap->ineq[i][1 + v_div + div]))
|
||||
continue;
|
||||
isl_int_add(ctx->normalize_gcd,
|
||||
bmap->ineq[i][0], bmap->ineq[j][0]);
|
||||
if (isl_int_ge(ctx->normalize_gcd,
|
||||
bmap->ineq[l][1 + v_div + div]))
|
||||
continue;
|
||||
bmap = set_residue_div(bmap, l, sum, div, v_div, total, i, j,
|
||||
progress);
|
||||
bmap = set_residue_div(bmap, l, sum, div, v_div, total, j, i,
|
||||
progress);
|
||||
}
|
||||
|
||||
return bmap;
|
||||
}
|
||||
|
||||
/* Given two constraints "k" and "l" that are opposite to each other,
|
||||
* except for the constant term, check if we can use them
|
||||
* to obtain an expression for one of the hitherto unknown divs or
|
||||
@ -1708,46 +2044,66 @@ static __isl_give isl_basic_map *check_for_residues(
|
||||
* "sum" is the sum of the constant terms of the constraints.
|
||||
* If this sum is strictly smaller than the coefficient of one
|
||||
* of the divs, then this pair can be used to define the div.
|
||||
* To avoid the introduction of circular definitions of divs, we
|
||||
* do not use the pair if the resulting expression would refer to
|
||||
* any other undefined divs or if any known div is defined in
|
||||
* terms of the unknown div.
|
||||
* Use the lower bound of this pair if it is better than
|
||||
* any previously known expression and
|
||||
* if there is no risk of introducing circular definitions.
|
||||
* If, moreover, this coefficient is a non-trivial multiple
|
||||
* of a value greater than the sum and if some other pair of constraints
|
||||
* can be found that can be used to eliminate coefficients
|
||||
* that are not a multiple of this value, then a more simplified
|
||||
* expression can be obtained.
|
||||
* "opposite" describes all pairs of opposite constraints.
|
||||
* It is an array of size equal to the number of inequality constraints
|
||||
* with as entries either
|
||||
* - zero, if the constraint has no opposite, or
|
||||
* - 1 + the position of the opposite constraint.
|
||||
*/
|
||||
static __isl_give isl_basic_map *check_for_div_constraints(
|
||||
__isl_take isl_basic_map *bmap, int k, int l, isl_int sum,
|
||||
int *progress)
|
||||
__isl_take isl_basic_map *bmap, int *opposite,
|
||||
int k, int l, isl_int sum, int *progress)
|
||||
{
|
||||
int i;
|
||||
unsigned total = isl_basic_map_offset(bmap, isl_dim_div);
|
||||
isl_size n_div = isl_basic_map_dim(bmap, isl_dim_div);
|
||||
|
||||
for (i = 0; i < bmap->n_div; ++i) {
|
||||
isl_bool set_div;
|
||||
if (n_div < 0)
|
||||
return isl_basic_map_free(bmap);
|
||||
|
||||
for (i = 0; i < n_div; ++i) {
|
||||
int div_set = 0;
|
||||
int c;
|
||||
|
||||
if (isl_int_is_zero(bmap->ineq[k][total + i]))
|
||||
continue;
|
||||
if (isl_int_abs_ge(sum, bmap->ineq[k][total + i]))
|
||||
continue;
|
||||
set_div = better_div_constraint(bmap, i, k);
|
||||
if (set_div >= 0 && set_div)
|
||||
set_div = ok_to_set_div_from_bound(bmap, i, k);
|
||||
if (set_div < 0)
|
||||
return isl_basic_map_free(bmap);
|
||||
if (!set_div)
|
||||
break;
|
||||
if (isl_int_is_pos(bmap->ineq[k][total + i]))
|
||||
bmap = set_div_from_lower_bound(bmap, i, k);
|
||||
c = k;
|
||||
else
|
||||
bmap = set_div_from_lower_bound(bmap, i, l);
|
||||
c = l;
|
||||
if (isl_int_ge(sum, bmap->ineq[c][total + i]))
|
||||
continue;
|
||||
bmap = check_for_residue_div(bmap, opposite, c, sum, i,
|
||||
&div_set);
|
||||
bmap = set_div_from_lower_bound_if_better(bmap, i,
|
||||
bmap->ineq[c], &div_set);
|
||||
if (!bmap)
|
||||
return NULL;
|
||||
if (!div_set)
|
||||
continue;
|
||||
mark_progress(progress);
|
||||
break;
|
||||
}
|
||||
return bmap;
|
||||
}
|
||||
|
||||
/* Look for pairs of constraints that have equal or opposite coefficients.
|
||||
* For each pair of constraints with equal coefficients, only keep
|
||||
* the one which imposes the most stringent constraint, i.e.,
|
||||
* the one with the smallest constant term.
|
||||
/* Exploit the pairs of inequality constraints of "bmap"
|
||||
* with opposite coefficients. They are described by "opposite",
|
||||
* an array of size equal to the number of inequality constraints
|
||||
* with as entries either
|
||||
* - zero, if the constraint has no opposite, or
|
||||
* - 1 + the position of the opposite constraint.
|
||||
* Detect (better) integer division expressions if "detect_divs" is set.
|
||||
* Set *progress if any progress is made.
|
||||
*
|
||||
* For each pair of constraints with opposite coefficients,
|
||||
* consider the sum of the constant terms.
|
||||
* If the sum is smaller than zero, then the constraints conflict.
|
||||
@ -1757,6 +2113,65 @@ static __isl_give isl_basic_map *check_for_div_constraints(
|
||||
* can be used to simplify any other constraints and/or,
|
||||
* if "detect_divs" is set, whether a (better) integer division definition
|
||||
* can be read off from the pair.
|
||||
*
|
||||
* Only check each pair once (with k < l).
|
||||
*/
|
||||
static __isl_give isl_basic_map *exploit_opposite_constraints(
|
||||
__isl_take isl_basic_map *bmap, int *opposite,
|
||||
int *progress, int detect_divs)
|
||||
{
|
||||
int k, l;
|
||||
isl_int sum;
|
||||
|
||||
if (!opposite)
|
||||
return bmap;
|
||||
isl_int_init(sum);
|
||||
for (k = 0; bmap && k < bmap->n_ineq-1; ++k) {
|
||||
if (!opposite[k])
|
||||
continue;
|
||||
l = opposite[k] - 1;
|
||||
if (l < k)
|
||||
continue;
|
||||
isl_int_add(sum, bmap->ineq[k][0], bmap->ineq[l][0]);
|
||||
if (isl_int_is_pos(sum)) {
|
||||
int residue = 0;
|
||||
|
||||
bmap = check_for_residues(bmap, k, l, sum, &residue);
|
||||
if (detect_divs)
|
||||
bmap = check_for_div_constraints(bmap, opposite,
|
||||
k, l, sum, progress);
|
||||
if (!residue)
|
||||
continue;
|
||||
mark_progress(progress);
|
||||
break;
|
||||
}
|
||||
if (isl_int_is_zero(sum)) {
|
||||
/* We need to break out of the loop after these
|
||||
* changes since the contents of the hash
|
||||
* will no longer be valid.
|
||||
* Plus, we probably we want to regauss first.
|
||||
*/
|
||||
mark_progress(progress);
|
||||
isl_basic_map_drop_inequality(bmap, l);
|
||||
isl_basic_map_inequality_to_equality(bmap, k);
|
||||
} else
|
||||
bmap = isl_basic_map_set_to_empty(bmap);
|
||||
break;
|
||||
}
|
||||
isl_int_clear(sum);
|
||||
free(opposite);
|
||||
|
||||
return bmap;
|
||||
}
|
||||
|
||||
/* Look for pairs of constraints that have equal or opposite coefficients.
|
||||
* Detect (better) integer division expressions if "detect_divs" is set.
|
||||
*
|
||||
* For each pair of constraints with equal coefficients, only keep
|
||||
* the one which imposes the most stringent constraint, i.e.,
|
||||
* the one with the smallest constant term.
|
||||
* Detect opposite constraints and handle them
|
||||
* in exploit_opposite_constraints.
|
||||
*/
|
||||
__isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints(
|
||||
__isl_take isl_basic_map *bmap, int *progress, int detect_divs)
|
||||
@ -1764,7 +2179,7 @@ __isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints(
|
||||
struct isl_constraint_index ci;
|
||||
int k, l, h;
|
||||
isl_size total = isl_basic_map_dim(bmap, isl_dim_all);
|
||||
isl_int sum;
|
||||
int *opposite;
|
||||
|
||||
if (total < 0 || bmap->n_ineq <= 1)
|
||||
return bmap;
|
||||
@ -1786,44 +2201,10 @@ __isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints(
|
||||
isl_basic_map_drop_inequality(bmap, k);
|
||||
--k;
|
||||
}
|
||||
isl_int_init(sum);
|
||||
for (k = 0; bmap && k < bmap->n_ineq-1; ++k) {
|
||||
isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total);
|
||||
h = hash_index(&ci, bmap, k);
|
||||
isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total);
|
||||
if (!ci.index[h])
|
||||
continue;
|
||||
l = ci.index[h] - &bmap->ineq[0];
|
||||
isl_int_add(sum, bmap->ineq[k][0], bmap->ineq[l][0]);
|
||||
if (isl_int_is_pos(sum)) {
|
||||
int residue = 0;
|
||||
|
||||
bmap = check_for_residues(bmap, k, l, sum, &residue);
|
||||
if (detect_divs)
|
||||
bmap = check_for_div_constraints(bmap, k, l,
|
||||
sum, progress);
|
||||
if (!residue)
|
||||
continue;
|
||||
mark_progress(progress);
|
||||
break;
|
||||
}
|
||||
if (isl_int_is_zero(sum)) {
|
||||
/* We need to break out of the loop after these
|
||||
* changes since the contents of the hash
|
||||
* will no longer be valid.
|
||||
* Plus, we probably we want to regauss first.
|
||||
*/
|
||||
mark_progress(progress);
|
||||
isl_basic_map_drop_inequality(bmap, l);
|
||||
isl_basic_map_inequality_to_equality(bmap, k);
|
||||
} else
|
||||
bmap = isl_basic_map_set_to_empty(bmap);
|
||||
break;
|
||||
}
|
||||
isl_int_clear(sum);
|
||||
|
||||
opposite = detect_opposites(&ci, bmap);
|
||||
constraint_index_free(&ci);
|
||||
return bmap;
|
||||
return exploit_opposite_constraints(bmap, opposite, progress,
|
||||
detect_divs);
|
||||
}
|
||||
|
||||
/* Detect all pairs of inequalities that form an equality.
|
||||
@ -5636,11 +6017,13 @@ static __isl_give isl_basic_map *isl_basic_map_drop_redundant_divs_ineq(
|
||||
if (defined)
|
||||
set_div = isl_bool_false;
|
||||
else
|
||||
set_div = ok_to_set_div_from_bound(bmap, i, last_pos);
|
||||
set_div = ok_to_set_div_from_bound(bmap, i,
|
||||
bmap->ineq[last_pos]);
|
||||
if (set_div < 0)
|
||||
return isl_basic_map_free(bmap);
|
||||
if (set_div) {
|
||||
bmap = set_div_from_lower_bound(bmap, i, last_pos);
|
||||
bmap = set_div_from_lower_bound(bmap, i,
|
||||
bmap->ineq[last_pos]);
|
||||
return drop_redundant_divs_again(bmap, pairs, 1);
|
||||
}
|
||||
pairs[i] = 0;
|
||||
@ -6087,8 +6470,14 @@ __isl_give isl_basic_map *isl_basic_map_reduce_coefficients(
|
||||
ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
|
||||
bmap = isl_basic_map_detect_inequality_pairs(bmap, &progress);
|
||||
if (progress) {
|
||||
isl_bool empty;
|
||||
|
||||
bmap = isl_basic_map_gauss(bmap, NULL);
|
||||
bmap = reduce_coefficients(bmap, &data);
|
||||
empty = isl_basic_map_plain_is_empty(bmap);
|
||||
if (empty < 0)
|
||||
goto error;
|
||||
if (!empty)
|
||||
bmap = reduce_coefficients(bmap, &data);
|
||||
bmap = eliminate_divs_eq(bmap, &progress);
|
||||
}
|
||||
}
|
||||
|
||||
58
polly/lib/External/isl/isl_test.c
vendored
58
polly/lib/External/isl/isl_test.c
vendored
@ -1567,63 +1567,6 @@ static int test_simple_hull(struct isl_ctx *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Inputs for isl_set_get_simple_fixed_box_hull tests.
|
||||
* "set" is the input set.
|
||||
* "offset" is the expected box offset.
|
||||
* "size" is the expected box size.
|
||||
*/
|
||||
static struct {
|
||||
const char *set;
|
||||
const char *offset;
|
||||
const char *size;
|
||||
} box_hull_tests[] = {
|
||||
{ "{ S[x, y] : 0 <= x, y < 10 }", "{ S[0, 0] }", "{ S[10, 10] }" },
|
||||
{ "[N] -> { S[x, y] : N <= x, y < N + 10 }",
|
||||
"[N] -> { S[N, N] }", "{ S[10, 10] }" },
|
||||
{ "{ S[x, y] : 0 <= x + y, x - y < 10 }",
|
||||
"{ S[0, -4] }", "{ S[10, 9] }" },
|
||||
{ "{ [i=0:10] : exists (e0, e1: 3e1 >= 1 + 2e0 and "
|
||||
"8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }",
|
||||
"{ [3] }", "{ [8] }" },
|
||||
{ "[N] -> { [w = 0:17] : exists (e0: w < 2N and "
|
||||
"-1 + w <= e0 <= w and 2e0 >= N + w and w <= 2e0 <= 15 + w) }",
|
||||
"[N] -> { [N] }", "{ [9] }" },
|
||||
};
|
||||
|
||||
/* Perform basic isl_set_get_simple_fixed_box_hull tests.
|
||||
*/
|
||||
static int test_box_hull(struct isl_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(box_hull_tests); ++i) {
|
||||
const char *str;
|
||||
isl_stat r;
|
||||
isl_set *set;
|
||||
isl_multi_aff *offset;
|
||||
isl_multi_val *size;
|
||||
isl_fixed_box *box;
|
||||
|
||||
set = isl_set_read_from_str(ctx, box_hull_tests[i].set);
|
||||
box = isl_set_get_simple_fixed_box_hull(set);
|
||||
offset = isl_fixed_box_get_offset(box);
|
||||
size = isl_fixed_box_get_size(box);
|
||||
str = box_hull_tests[i].offset;
|
||||
r = multi_aff_check_plain_equal(offset, str);
|
||||
str = box_hull_tests[i].size;
|
||||
if (r >= 0)
|
||||
r = multi_val_check_plain_equal(size, str);
|
||||
isl_multi_aff_free(offset);
|
||||
isl_multi_val_free(size);
|
||||
isl_fixed_box_free(box);
|
||||
isl_set_free(set);
|
||||
if (r < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_convex_hull_case(struct isl_ctx *ctx, const char *name)
|
||||
{
|
||||
char *filename;
|
||||
@ -10800,7 +10743,6 @@ struct {
|
||||
{ "recession cone", &test_recession_cone },
|
||||
{ "affine hull", &test_affine_hull },
|
||||
{ "simple_hull", &test_simple_hull },
|
||||
{ "box hull", &test_box_hull },
|
||||
{ "coalesce", &test_coalesce },
|
||||
{ "factorize", &test_factorize },
|
||||
{ "subset", &test_subset },
|
||||
|
||||
54
polly/lib/External/isl/isl_test2.cc
vendored
54
polly/lib/External/isl/isl_test2.cc
vendored
@ -101,6 +101,9 @@ struct ternary {
|
||||
* The spelling depends on the isl type and
|
||||
* in particular on whether an equality method is available or
|
||||
* whether only obvious equality can be tested.
|
||||
*
|
||||
* Since isl::multi_val has both an is_equal and a plain_is_equal,
|
||||
* use a specific overload for isl::multi_val that calls is_equal.
|
||||
*/
|
||||
template <typename T, typename std::decay<decltype(
|
||||
std::declval<T>().is_equal(std::declval<T>()))>::type = true>
|
||||
@ -114,6 +117,10 @@ static bool is_equal(const T &a, const T &b)
|
||||
{
|
||||
return a.plain_is_equal(b);
|
||||
}
|
||||
static bool is_equal(const isl::multi_val &a, const isl::multi_val &b)
|
||||
{
|
||||
return a.is_equal(b);
|
||||
}
|
||||
|
||||
/* A helper macro for throwing an isl::exception_invalid with message "msg".
|
||||
*/
|
||||
@ -431,6 +438,52 @@ static void test_fixed_power(isl::ctx ctx)
|
||||
});
|
||||
}
|
||||
|
||||
/* Perform basic simple fixed box hull tests.
|
||||
*/
|
||||
static void test_box_hull(isl::ctx ctx)
|
||||
{
|
||||
C(&isl::set::simple_fixed_box_hull, {
|
||||
{ "{ S[x, y] : 0 <= x, y < 10 }",
|
||||
"{ offset: { S[0, 0] }, size: { S[10, 10] } }" },
|
||||
{ "[N] -> { S[x, y] : N <= x, y < N + 10 }",
|
||||
"{ offset: [N] -> { S[(N), (N)] }, size: { S[10, 10] } }" },
|
||||
{ "{ S[x, y] : 0 <= x + y, x - y < 10 }",
|
||||
"{ offset: { S[0, -4] }, size: { S[10, 9] } }" },
|
||||
{ "{ [i=0:10] : exists (e0, e1: 3e1 >= 1 + 2e0 and "
|
||||
"8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }",
|
||||
"{ offset: { [3] }, size: { [8] } }" },
|
||||
{ "[N] -> { [w = 0:17] : exists (e0: w < 2N and "
|
||||
"-1 + w <= e0 <= w and 2e0 >= N + w and w <= 2e0 <= 15 + w) }",
|
||||
"{ offset: [N] -> { [N] }, size: { [9] } }" },
|
||||
{ "[N] -> { [N//2:N//2+4] }",
|
||||
"{ offset: [N] -> { [N//2] }, size: { [5] } }" },
|
||||
{ "[N] -> { [N//2+N//3:N//2+N//3+4] }",
|
||||
"{ offset: [N] -> { [N//2+N//3] }, size: { [5] } }" },
|
||||
{ "[N] -> { [a=0:59, b=0:1] : 15N - a <= 60b <= 59 + 15N - a and "
|
||||
"-22 + 20b <= 20*floor((-1 + 15N - a)/60) < 20b and "
|
||||
"60*floor((-1 + 15N - a)/60) <= -46 + 15N - a }",
|
||||
"{ offset: [N] -> { [(15*((N) mod 4)), (floor((N)/4))] }, "
|
||||
"size: { [15, 1] } }" },
|
||||
{ "{ [i=-3:7] : i mod 4 = 0 }",
|
||||
"{ offset: { [(0)] }, size: { [5] } }" },
|
||||
{ "[N] -> { [i, N - 4i] : -14 + N <= 16i <= 1 + N }",
|
||||
"{ offset: [N] -> { [(floor((1 + N)/16)), "
|
||||
"(4 + N + 4*floor((-2 - N)/16))] }, "
|
||||
"size: { [1, 1] } }" },
|
||||
});
|
||||
|
||||
C(&isl::map::range_simple_fixed_box_hull, {
|
||||
{ "{ [N] -> [i, N - 4i] : -14 + N <= 16i <= 1 + N }",
|
||||
"{ offset: { [N] -> [(floor((1 + N)/16)), "
|
||||
"(4 + N + 4*floor((-2 - N)/16))] }, "
|
||||
"size: { [1, 1] } }" },
|
||||
{ "{ [N] -> [i, j] : 4j = N - i and -1 + 3N <= 4i <= 14 + 3N }",
|
||||
"{ offset: { [N] -> [(4 + N + 4*floor((-2 - N)/16)), "
|
||||
"(floor((1 + N)/16))] }, "
|
||||
"size: { [1, 1] } }" },
|
||||
});
|
||||
}
|
||||
|
||||
/* Perform some basic intersection tests.
|
||||
*/
|
||||
static void test_intersect(isl::ctx ctx)
|
||||
@ -913,6 +966,7 @@ static std::vector<std::pair<const char *, void (*)(isl::ctx)>> tests =
|
||||
{ "conversion", &test_conversion },
|
||||
{ "preimage", &test_preimage },
|
||||
{ "fixed power", &test_fixed_power },
|
||||
{ "box hull", &test_box_hull },
|
||||
{ "intersect", &test_intersect },
|
||||
{ "lexmin", &test_lexmin },
|
||||
{ "gist", &test_gist },
|
||||
|
||||
39
polly/lib/External/isl/isl_union_map.c
vendored
39
polly/lib/External/isl/isl_union_map.c
vendored
@ -2198,6 +2198,45 @@ __isl_give isl_union_set *isl_union_set_simple_hull(
|
||||
return isl_union_map_simple_hull(uset);
|
||||
}
|
||||
|
||||
/* Compute a superset of the convex hull of "map" that is described
|
||||
* by only the constraints in the constituents of "map" and
|
||||
* return the result as an isl_map.
|
||||
* In particular, the result is composed of constraints that appear
|
||||
* in each of the basic maps of "map".
|
||||
*/
|
||||
static __isl_give isl_map *isl_map_plain_unshifted_simple_hull_map(
|
||||
__isl_take isl_map *map)
|
||||
{
|
||||
return isl_map_from_basic_map(isl_map_plain_unshifted_simple_hull(map));
|
||||
}
|
||||
|
||||
/* For each map in "umap", compute a superset of the convex hull
|
||||
* that is described by only the constraints in the constituents of that map and
|
||||
* collect the results.
|
||||
* In particular, each result is composed of constraints that appear
|
||||
* in each of the basic maps of the corresponding map.
|
||||
*/
|
||||
__isl_give isl_union_map *isl_union_map_plain_unshifted_simple_hull(
|
||||
__isl_take isl_union_map *umap)
|
||||
{
|
||||
return total(umap, &isl_map_plain_unshifted_simple_hull_map);
|
||||
}
|
||||
|
||||
/* For each set in "uset", compute a superset of the convex hull
|
||||
* that is described by only the constraints in the constituents of that set and
|
||||
* collect the results.
|
||||
* In particular, each result is composed of constraints that appear
|
||||
* in each of the basic sets of the corresponding set.
|
||||
*/
|
||||
__isl_give isl_union_set *isl_union_set_plain_unshifted_simple_hull(
|
||||
__isl_take isl_union_set *uset)
|
||||
{
|
||||
isl_union_map *umap;
|
||||
|
||||
umap = isl_union_map_plain_unshifted_simple_hull(uset_to_umap(uset));
|
||||
return uset_from_umap(umap);
|
||||
}
|
||||
|
||||
static __isl_give isl_union_map *inplace(__isl_take isl_union_map *umap,
|
||||
__isl_give isl_map *(*fn)(__isl_take isl_map *))
|
||||
{
|
||||
|
||||
11
polly/lib/External/isl/isl_val.c
vendored
11
polly/lib/External/isl/isl_val.c
vendored
@ -1589,6 +1589,17 @@ __isl_give isl_val *isl_val_zero_on_domain(__isl_take isl_local_space *ls)
|
||||
#include <isl_multi_tuple_id_templ.c>
|
||||
#include <isl_multi_zero_templ.c>
|
||||
|
||||
/* Is "mv1" equal to "mv2"?
|
||||
*
|
||||
* Call the generic isl_multi_val_plain_is_equal, which compares values
|
||||
* using isl_val_plain_is_equal, i.e., isl_val_eq.
|
||||
*/
|
||||
isl_bool isl_multi_val_is_equal(__isl_keep isl_multi_val *mv1,
|
||||
__isl_keep isl_multi_val *mv2)
|
||||
{
|
||||
return isl_multi_val_plain_is_equal(mv1, mv2);
|
||||
}
|
||||
|
||||
/* Does "mv" consist of only zeros?
|
||||
*/
|
||||
isl_bool isl_multi_val_is_zero(__isl_keep isl_multi_val *mv)
|
||||
|
||||
19
polly/lib/External/isl/test_inputs/codegen/polly.c
vendored
Normal file
19
polly/lib/External/isl/test_inputs/codegen/polly.c
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
if (p_0 >= p_1 + 1) {
|
||||
for (int c0 = 0; c0 <= p_1 - 4 * floord(p_1 + 2, 4); c0 += 1)
|
||||
Stmt2(c0);
|
||||
if (4 * floord(p_1 + 2, 4) >= p_1 + 1)
|
||||
for (int c0 = 0; c0 <= p_1 - 4 * floord(p_1 + 2, 4) + 4; c0 += 1)
|
||||
Stmt2(c0);
|
||||
} else if (p_0 >= p_1 + 4 * floord(p_0 - p_1, 4) + 1) {
|
||||
for (int c0 = 0; c0 <= p_0 - 4 * floord(p_0 + 2, 4); c0 += 1)
|
||||
Stmt2(c0);
|
||||
if (4 * floord(p_0 + 2, 4) >= p_0 + 1)
|
||||
for (int c0 = 0; c0 <= p_0 - 4 * floord(p_0 + 2, 4) + 4; c0 += 1)
|
||||
Stmt2(c0);
|
||||
} else if (4 * floord(p_0 + 2, 4) >= p_0 + 1) {
|
||||
for (int c0 = 0; c0 <= p_0 - 4 * floord(p_0 + 2, 4) + 4; c0 += 1)
|
||||
Stmt2(c0);
|
||||
} else {
|
||||
for (int c0 = 0; c0 <= p_0 - 4 * floord(p_0 + 2, 4); c0 += 1)
|
||||
Stmt2(c0);
|
||||
}
|
||||
7
polly/lib/External/isl/test_inputs/codegen/polly.st
vendored
Normal file
7
polly/lib/External/isl/test_inputs/codegen/polly.st
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# A Polly generated test case that would cause a failure
|
||||
# in isl_basic_map_reduce_coefficients in an earlier version of isl.
|
||||
domain: "[p_0, p_1] -> { Stmt2[i0] : i0 >= 0 and ((p_1 < p_0 and 4*floor((2 + p_1)/4) <= p_1 - i0) or (p_1 >= p_0 and 4*floor((p_0 - p_1)/4) < p_0 - p_1 and 4*floor((2 + p_0)/4) <= p_0 - i0) or (p_1 < p_0 and p_1 < 4*floor((2 + p_1)/4) <= 4 + p_1 - i0 and 4*floor((p_0 - p_1)/4) < p_0 - p_1) or (p_1 >= p_0 and 4*floor((p_0 - p_1)/4) < p_0 - p_1 and p_0 < 4*floor((2 + p_0)/4) <= 4 + p_0 - i0) or ((2 + p_0) mod 4 = 6 + p_1 + 4*floor((-1 - p_1)/4) and p_1 >= p_0 and -4 - p_1 + i0 <= 4*floor((-1 - p_1)/4) <= -3 - p_1) or ((2 + p_0) mod 4 = 2 + p_1 + 4*floor((1 - p_1)/4) and p_1 >= p_0 and 4*floor((1 - p_1)/4) >= -4 - p_1 + i0 and 4*floor((1 - p_1)/4) < -p_1) or ((-p_0 + p_1) mod 4 = 0 and p_1 <= -4 + p_0 and p_1 < 4*floor((2 + p_1)/4) <= 4 + p_1 - i0)) }"
|
||||
child:
|
||||
context: "[p_0, p_1] -> { [] : p_0 >= -2147483648 and p_0 <= 2147483647 and p_1 >= -2147483648 and p_1 <= 2147483647 }"
|
||||
child:
|
||||
schedule: "[p_0, p_1] -> [{ Stmt2[i0] -> [(i0)] }]"
|
||||
Loading…
x
Reference in New Issue
Block a user