Update to isl-0.20-65-gb822a210
authorTobias Grosser <tobias@grosser.es>
Thu, 9 Aug 2018 05:07:05 +0000 (05:07 +0000)
committerTobias Grosser <tobias@grosser.es>
Thu, 9 Aug 2018 05:07:05 +0000 (05:07 +0000)
This update fixes https://https:/llvm.org/PR38348. Thanks Michael for
reporting the issue to isl and Sven for fixing the issue.

llvm-svn: 339311

22 files changed:
polly/lib/External/isl/GIT_HEAD_ID
polly/lib/External/isl/doc/user.pod
polly/lib/External/isl/include/isl/cpp-checked.h
polly/lib/External/isl/include/isl/cpp.h
polly/lib/External/isl/include/isl/options.h
polly/lib/External/isl/include/isl/space.h
polly/lib/External/isl/include/isl/val.h
polly/lib/External/isl/interface/cpp.cc
polly/lib/External/isl/interface/cpp.h
polly/lib/External/isl/interface/generator.cc
polly/lib/External/isl/interface/generator.h
polly/lib/External/isl/interface/isl.py
polly/lib/External/isl/interface/python.cc
polly/lib/External/isl/isl_ast_codegen.c
polly/lib/External/isl/isl_coalesce.c
polly/lib/External/isl/isl_map.c
polly/lib/External/isl/isl_map_simplify.c
polly/lib/External/isl/isl_options.c
polly/lib/External/isl/isl_options_private.h
polly/lib/External/isl/isl_space.c
polly/lib/External/isl/isl_test.c
polly/lib/External/isl/isl_val.c

index 18831d2..c8e57b5 100644 (file)
@@ -795,6 +795,7 @@ The following binary operations are available on C<isl_val>s.
 On integer values, we additionally have the following operations.
 
        #include <isl/val.h>
+       __isl_give isl_val *isl_val_pow2(__isl_take isl_val *v);
        __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v);
        __isl_give isl_val *isl_val_mod(__isl_take isl_val *v1,
                __isl_take isl_val *v2);
@@ -804,6 +805,7 @@ On integer values, we additionally have the following operations.
                __isl_take isl_val *v2, __isl_give isl_val **x,
                __isl_give isl_val **y);
 
+C<isl_val_2exp> is an alternative name for C<isl_val_pow2>.
 The function C<isl_val_gcdext> returns the greatest common divisor g
 of C<v1> and C<v2> as well as two integers C<*x> and C<*y> such
 that C<*x> * C<v1> + C<*y> * C<v2> = g.
@@ -5128,6 +5130,17 @@ the following option.
        int isl_options_get_coalesce_bounded_wrapping(
                isl_ctx *ctx);
 
+One of the other methods tries to combine pairs of basic sets
+with different local variables, treating them as existentially
+quantified variables even if they have known (but different)
+integer division expressions.  The result may then also have
+existentially quantified variables.  Turning on the following
+option prevents this from happening.
+
+       isl_stat isl_options_set_coalesce_preserve_locals(
+               isl_ctx *ctx, int val);
+       int isl_options_get_coalesce_preserve_locals(isl_ctx *ctx);
+
 =item * Detecting equalities
 
        __isl_give isl_basic_set *isl_basic_set_detect_equalities(
index aaa51a2..1cd0506 100644 (file)
@@ -1200,6 +1200,7 @@ public:
   static inline val neginfty(ctx ctx);
   static inline val negone(ctx ctx);
   static inline val one(ctx ctx);
+  inline val pow2() const;
   inline int sgn() const;
   inline val sub(val v2) const;
   inline val trunc() const;
@@ -4852,6 +4853,12 @@ val val::one(ctx ctx)
   return manage(res);
 }
 
+val val::pow2() const
+{
+  auto res = isl_val_pow2(copy());
+  return manage(res);
+}
+
 int val::sgn() const
 {
   auto res = isl_val_sgn(get());
index 3062d0f..de0da10 100644 (file)
@@ -1322,6 +1322,7 @@ public:
   static inline val neginfty(ctx ctx);
   static inline val negone(ctx ctx);
   static inline val one(ctx ctx);
+  inline val pow2() const;
   inline int sgn() const;
   inline val sub(val v2) const;
   inline val trunc() const;
@@ -1356,7 +1357,7 @@ aff::aff(const aff &obj)
   auto ctx = isl_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -1636,7 +1637,7 @@ ast_build::ast_build(const ast_build &obj)
   auto ctx = isl_ast_build_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -1808,7 +1809,7 @@ ast_expr::ast_expr(const ast_expr &obj)
   auto ctx = isl_ast_expr_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -1888,7 +1889,7 @@ ast_node::ast_node(const ast_node &obj)
   auto ctx = isl_ast_node_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -1968,7 +1969,7 @@ basic_map::basic_map(const basic_map &obj)
   auto ctx = isl_basic_map_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -2284,7 +2285,7 @@ basic_set::basic_set(const basic_set &obj)
   auto ctx = isl_basic_set_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -2575,7 +2576,7 @@ map::map(const map &obj)
   auto ctx = isl_map_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -2779,7 +2780,7 @@ void map::foreach_basic_map(const std::function<void(basic_map)> &fn) const
     std::rethrow_exception(fn_data.eptr);
   if (res < 0)
     exception::throw_last_error(ctx);
-  return void(res);
+  return;
 }
 
 map map::gist(map context) const
@@ -3074,7 +3075,7 @@ multi_aff::multi_aff(const multi_aff &obj)
   auto ctx = isl_multi_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -3221,7 +3222,7 @@ multi_pw_aff::multi_pw_aff(const multi_pw_aff &obj)
   auto ctx = isl_multi_pw_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -3414,7 +3415,7 @@ multi_union_pw_aff::multi_union_pw_aff(const multi_union_pw_aff &obj)
   auto ctx = isl_multi_union_pw_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -3572,7 +3573,7 @@ multi_val::multi_val(const multi_val &obj)
   auto ctx = isl_multi_val_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -3688,7 +3689,7 @@ point::point(const point &obj)
   auto ctx = isl_point_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -3757,7 +3758,7 @@ pw_aff::pw_aff(const pw_aff &obj)
   auto ctx = isl_pw_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -4144,7 +4145,7 @@ pw_multi_aff::pw_multi_aff(const pw_multi_aff &obj)
   auto ctx = isl_pw_multi_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -4326,7 +4327,7 @@ schedule::schedule(const schedule &obj)
   auto ctx = isl_schedule_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -4438,7 +4439,7 @@ schedule_constraints::schedule_constraints(const schedule_constraints &obj)
   auto ctx = isl_schedule_constraints_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -4682,7 +4683,7 @@ schedule_node::schedule_node(const schedule_node &obj)
   auto ctx = isl_schedule_node_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -4846,7 +4847,7 @@ set::set(const set &obj)
   auto ctx = isl_set_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -5013,7 +5014,7 @@ void set::foreach_basic_set(const std::function<void(basic_set)> &fn) const
     std::rethrow_exception(fn_data.eptr);
   if (res < 0)
     exception::throw_last_error(ctx);
-  return void(res);
+  return;
 }
 
 val set::get_stride(int pos) const
@@ -5296,7 +5297,7 @@ union_access_info::union_access_info(const union_access_info &obj)
   auto ctx = isl_union_access_info_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -5447,7 +5448,7 @@ union_flow::union_flow(const union_flow &obj)
   auto ctx = isl_union_flow_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -5587,7 +5588,7 @@ union_map::union_map(const union_map &obj)
   auto ctx = isl_union_map_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -5886,7 +5887,7 @@ void union_map::foreach_map(const std::function<void(map)> &fn) const
     std::rethrow_exception(fn_data.eptr);
   if (res < 0)
     exception::throw_last_error(ctx);
-  return void(res);
+  return;
 }
 
 union_map union_map::from(union_pw_multi_aff upma)
@@ -6361,7 +6362,7 @@ union_pw_aff::union_pw_aff(const union_pw_aff &obj)
   auto ctx = isl_union_pw_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -6484,7 +6485,7 @@ union_pw_multi_aff::union_pw_multi_aff(const union_pw_multi_aff &obj)
   auto ctx = isl_union_pw_multi_aff_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -6630,7 +6631,7 @@ union_set::union_set(const union_set &obj)
   auto ctx = isl_union_set_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -6796,7 +6797,7 @@ void union_set::foreach_point(const std::function<void(point)> &fn) const
     std::rethrow_exception(fn_data.eptr);
   if (res < 0)
     exception::throw_last_error(ctx);
-  return void(res);
+  return;
 }
 
 void union_set::foreach_set(const std::function<void(set)> &fn) const
@@ -6824,7 +6825,7 @@ void union_set::foreach_set(const std::function<void(set)> &fn) const
     std::rethrow_exception(fn_data.eptr);
   if (res < 0)
     exception::throw_last_error(ctx);
-  return void(res);
+  return;
 }
 
 union_set union_set::gist(union_set context) const
@@ -7083,7 +7084,7 @@ val::val(const val &obj)
   auto ctx = isl_val_get_ctx(obj.ptr);
   options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
   ptr = obj.copy();
-  if (obj.ptr && !ptr)
+  if (!ptr)
     exception::throw_last_error(ctx);
 }
 
@@ -7578,6 +7579,18 @@ val val::one(ctx ctx)
   return manage(res);
 }
 
+val val::pow2() const
+{
+  if (!ptr)
+    exception::throw_NULL_input(__FILE__, __LINE__);
+  auto ctx = get_ctx();
+  options_scoped_set_on_error saved_on_error(ctx, exception::on_error);
+  auto res = isl_val_pow2(copy());
+  if (!res)
+    exception::throw_last_error(ctx);
+  return manage(res);
+}
+
 int val::sgn() const
 {
   if (!ptr)
index c09dee6..1738155 100644 (file)
@@ -46,6 +46,9 @@ int isl_options_get_pip_symmetry(isl_ctx *ctx);
 isl_stat isl_options_set_coalesce_bounded_wrapping(isl_ctx *ctx, int val);
 int isl_options_get_coalesce_bounded_wrapping(isl_ctx *ctx);
 
+isl_stat isl_options_set_coalesce_preserve_locals(isl_ctx *ctx, int val);
+int isl_options_get_coalesce_preserve_locals(isl_ctx *ctx);
+
 #if defined(__cplusplus)
 }
 #endif
index deb592b..40a333e 100644 (file)
@@ -79,7 +79,7 @@ __isl_give isl_space *isl_space_add_dims(__isl_take isl_space *space,
 __isl_give isl_space *isl_space_move_dims(__isl_take isl_space *space,
        enum isl_dim_type dst_type, unsigned dst_pos,
        enum isl_dim_type src_type, unsigned src_pos, unsigned n);
-__isl_give isl_space *isl_space_insert_dims(__isl_take isl_space *dim,
+__isl_give isl_space *isl_space_insert_dims(__isl_take isl_space *space,
        enum isl_dim_type type, unsigned pos, unsigned n);
 __isl_give isl_space *isl_space_join(__isl_take isl_space *left,
        __isl_take isl_space *right);
index aacad39..faf3e15 100644 (file)
@@ -64,6 +64,8 @@ __isl_export
 __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v);
 __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v);
 __isl_export
+__isl_give isl_val *isl_val_pow2(__isl_take isl_val *v);
+__isl_export
 __isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2);
 __isl_export
 __isl_give isl_val *isl_val_max(__isl_take isl_val *v1, __isl_take isl_val *v2);
index 67deece..a52e6fe 100644 (file)
@@ -448,6 +448,50 @@ static void print_throw_NULL_input(ostream &os)
        osprintf(os, "    exception::throw_NULL_input(__FILE__, __LINE__);\n");
 }
 
+/* Print code that checks that "ptr" is not NULL at input.
+ *
+ * Omit the check if checked C++ bindings are being generated.
+ */
+void cpp_generator::print_check_ptr(ostream &os, const char *ptr)
+{
+       if (checked)
+               return;
+
+       osprintf(os, "  if (!%s)\n", ptr);
+       print_throw_NULL_input(os);
+}
+
+/* Print code that checks that "ptr" is not NULL at input and
+ * that saves a copy of the isl_ctx of "ptr" for a later check.
+ *
+ * Omit the check if checked C++ bindings are being generated.
+ */
+void cpp_generator::print_check_ptr_start(ostream &os, const isl_class &clazz,
+       const char *ptr)
+{
+       if (checked)
+               return;
+
+       print_check_ptr(os, ptr);
+       osprintf(os, "  auto ctx = %s_get_ctx(%s);\n", clazz.name.c_str(), ptr);
+       print_on_error_continue(os);
+}
+
+/* Print code that checks that "ptr" is not NULL at the end.
+ * A copy of the isl_ctx is expected to have been saved by
+ * code generated by print_check_ptr_start.
+ *
+ * Omit the check if checked C++ bindings are being generated.
+ */
+void cpp_generator::print_check_ptr_end(ostream &os, const char *ptr)
+{
+       if (checked)
+               return;
+
+       osprintf(os, "  if (!%s)\n", ptr);
+       print_throw_last_error(os);
+}
+
 /* Print implementation of global factory functions to "os".
  *
  * Each class has two global factory functions:
@@ -470,26 +514,15 @@ void cpp_generator::print_class_factory_impl(ostream &os,
        const char *cppname = cppstring.c_str();
 
        osprintf(os, "%s manage(__isl_take %s *ptr) {\n", cppname, name);
-       if (!checked) {
-               osprintf(os, "  if (!ptr)\n");
-               print_throw_NULL_input(os);
-       }
+       print_check_ptr(os, "ptr");
        osprintf(os, "  return %s(ptr);\n", cppname);
        osprintf(os, "}\n");
 
        osprintf(os, "%s manage_copy(__isl_keep %s *ptr) {\n", cppname,
                name);
-       if (!checked) {
-               osprintf(os, "  if (!ptr)\n");
-               print_throw_NULL_input(os);
-               osprintf(os, "  auto ctx = %s_get_ctx(ptr);\n", name);
-               print_on_error_continue(os);
-       }
+       print_check_ptr_start(os, clazz, "ptr");
        osprintf(os, "  ptr = %s_copy(ptr);\n", name);
-       if (!checked) {
-               osprintf(os, "  if (!ptr)\n");
-               print_throw_last_error(os);
-       }
+       print_check_ptr_end(os, "ptr");
        osprintf(os, "  return %s(ptr);\n", cppname);
        osprintf(os, "}\n");
 }
@@ -519,7 +552,6 @@ void cpp_generator::print_private_constructors_impl(ostream &os,
 void cpp_generator::print_public_constructors_impl(ostream &os,
        const isl_class &clazz)
 {
-       const char *name = clazz.name.c_str();
        std::string cppstring = type2cpp(clazz);
        const char *cppname = cppstring.c_str();
 
@@ -527,17 +559,9 @@ void cpp_generator::print_public_constructors_impl(ostream &os,
        osprintf(os, "%s::%s(const %s &obj)\n    : ptr(nullptr)\n",
                 cppname, cppname, cppname);
        osprintf(os, "{\n");
-       if (!checked) {
-               osprintf(os, "  if (!obj.ptr)\n");
-               print_throw_NULL_input(os);
-               osprintf(os, "  auto ctx = %s_get_ctx(obj.ptr);\n", name);
-               print_on_error_continue(os);
-       }
+       print_check_ptr_start(os, clazz, "obj.ptr");
        osprintf(os, "  ptr = obj.copy();\n");
-       if (!checked) {
-               osprintf(os, "  if (obj.ptr && !ptr)\n");
-               print_throw_last_error(os);
-       }
+       print_check_ptr_end(os, "ptr");
        osprintf(os, "}\n");
 }
 
@@ -879,16 +903,10 @@ void cpp_generator::print_exceptional_execution_check(ostream &os,
        print_throw_last_error(os);
 }
 
-/* Print definition for "method" in class "clazz" to "os".
- *
- * "kind" specifies the kind of method that should be generated.
+/* Print the return statement of the C++ method corresponding
+ * to the C function "method" in class "clazz" to "os".
  *
- * This method distinguishes three kinds of methods: member methods, static
- * methods, and constructors.
- *
- * Member methods call "method" by passing to the underlying isl function the
- * isl object belonging to "this" as first argument and the remaining arguments
- * as subsequent arguments. The result of the isl function is returned as a new
+ * The result of the isl function is returned as a new
  * object if the underlying isl function returns an isl_* ptr, as a bool
  * if the isl function returns an isl_bool, as void if the isl functions
  * returns an isl_stat,
@@ -898,6 +916,38 @@ void cpp_generator::print_exceptional_execution_check(ostream &os,
  * then an isl_bool return type is transformed into a boolean and
  * an isl_stat into a stat since no exceptions can be generated
  * on negative results from the isl function.
+ */
+void cpp_generator::print_method_return(ostream &os, const isl_class &clazz,
+       FunctionDecl *method)
+{
+       QualType return_type = method->getReturnType();
+
+       if (is_isl_type(return_type) ||
+                   (checked &&
+                    (is_isl_bool(return_type) || is_isl_stat(return_type)))) {
+               osprintf(os, "  return manage(res);\n");
+       } else if (is_isl_stat(return_type)) {
+               osprintf(os, "  return;\n");
+       } else if (is_string(return_type)) {
+               osprintf(os, "  std::string tmp(res);\n");
+               if (gives(method))
+                       osprintf(os, "  free(res);\n");
+               osprintf(os, "  return tmp;\n");
+       } else {
+               osprintf(os, "  return res;\n");
+       }
+}
+
+/* Print definition for "method" in class "clazz" to "os".
+ *
+ * "kind" specifies the kind of method that should be generated.
+ *
+ * This method distinguishes three kinds of methods: member methods, static
+ * methods, and constructors.
+ *
+ * Member methods call "method" by passing to the underlying isl function the
+ * isl object belonging to "this" as first argument and the remaining arguments
+ * as subsequent arguments.
  *
  * Static methods call "method" by passing all arguments to the underlying isl
  * function, as no this-pointer is available. The result is a newly managed
@@ -925,9 +975,6 @@ void cpp_generator::print_method_impl(ostream &os, const isl_class &clazz,
 {
        string methodname = method->getName();
        int num_params = method->getNumParams();
-       QualType return_type = method->getReturnType();
-       string rettype_str = type2cpp(return_type);
-       bool has_callback = false;
 
        print_method_header(os, clazz, method, false, kind);
        osprintf(os, "{\n");
@@ -938,7 +985,6 @@ void cpp_generator::print_method_impl(ostream &os, const isl_class &clazz,
        for (int i = 0; i < num_params; ++i) {
                ParmVarDecl *param = method->getParamDecl(i);
                if (is_callback(param->getType())) {
-                       has_callback = true;
                        num_params -= 1;
                        print_callback_local(os, param);
                }
@@ -963,19 +1009,8 @@ void cpp_generator::print_method_impl(ostream &os, const isl_class &clazz,
        print_exceptional_execution_check(os, method);
        if (kind == function_kind_constructor) {
                osprintf(os, "  ptr = res;\n");
-       } else if (is_isl_type(return_type) ||
-                   (checked &&
-                    (is_isl_bool(return_type) || is_isl_stat(return_type)))) {
-               osprintf(os, "  return manage(res);\n");
-       } else if (has_callback) {
-               osprintf(os, "  return %s(res);\n", rettype_str.c_str());
-       } else if (is_string(return_type)) {
-               osprintf(os, "  std::string tmp(res);\n");
-               if (gives(method))
-                       osprintf(os, "  free(res);\n");
-               osprintf(os, "  return tmp;\n");
        } else {
-               osprintf(os, "  return res;\n");
+               print_method_return(os, clazz, method);
        }
 
        osprintf(os, "}\n");
@@ -1109,7 +1144,7 @@ string cpp_generator::generate_callback_args(QualType type, bool cpp)
        const FunctionProtoType *callback;
        int num_params;
 
-       callback = type->getPointeeType()->getAs<FunctionProtoType>();
+       callback = extract_prototype(type);
        num_params = callback->getNumArgs();
        if (cpp)
                num_params--;
@@ -1145,7 +1180,7 @@ string cpp_generator::generate_callback_args(QualType type, bool cpp)
 string cpp_generator::generate_callback_type(QualType type)
 {
        std::string type_str;
-       const FunctionProtoType *callback = type->getPointeeType()->getAs<FunctionProtoType>();
+       const FunctionProtoType *callback = extract_prototype(type);
        QualType return_type = callback->getReturnType();
        string rettype_str = type2cpp(return_type);
 
@@ -1271,7 +1306,7 @@ void cpp_generator::print_callback_local(ostream &os, ParmVarDecl *param)
        c_args = generate_callback_args(ptype, false);
        cpp_args = generate_callback_type(ptype);
 
-       callback = ptype->getPointeeType()->getAs<FunctionProtoType>();
+       callback = extract_prototype(ptype);
        rettype = callback->getReturnType().getAsString();
        num_params = callback->getNumArgs();
 
index b46d37f..0e97c71 100644 (file)
@@ -50,6 +50,10 @@ private:
                FunctionDecl *method, function_kind kind);
        void print_implementations(ostream &os);
        void print_class_impl(ostream &os, const isl_class &clazz);
+       void print_check_ptr(ostream &os, const char *ptr);
+       void print_check_ptr_start(ostream &os, const isl_class &clazz,
+               const char *ptr);
+       void print_check_ptr_end(ostream &os, const char *ptr);
        void print_class_factory_impl(ostream &os, const isl_class &clazz);
        void print_private_constructors_impl(ostream &os,
                const isl_class &clazz);
@@ -70,6 +74,8 @@ private:
        void print_on_error_continue(ostream &os);
        void print_exceptional_execution_check(ostream &os,
                FunctionDecl *method);
+       void print_method_return(ostream &os, const isl_class &clazz,
+               FunctionDecl *method);
        void print_method_impl(ostream &os, const isl_class &clazz,
                FunctionDecl *method, function_kind kind);
        void print_method_param_use(ostream &os, ParmVarDecl *param,
index c357285..fee2347 100644 (file)
@@ -110,13 +110,14 @@ generator::generator(SourceManager &SM, set<RecordDecl *> &exported_types,
 
        for (in = exported_functions.begin(); in != exported_functions.end();
             ++in) {
-               isl_class *c = method2class(*in);
+               FunctionDecl *method = *in;
+               isl_class *c = method2class(method);
+
                if (!c)
                        continue;
-               if (is_constructor(*in)) {
-                       c->constructors.insert(*in);
+               if (is_constructor(method)) {
+                       c->constructors.insert(method);
                } else {
-                       FunctionDecl *method = *in;
                        string fullname = c->name_without_type_suffix(method);
                        c->methods[fullname].insert(method);
                }
@@ -412,6 +413,14 @@ string generator::extract_type(QualType type)
        die("Cannot extract type from non-pointer type");
 }
 
+/* Given the type of a function pointer, return the corresponding
+ * function prototype.
+ */
+const FunctionProtoType *generator::extract_prototype(QualType type)
+{
+       return type->getPointeeType()->getAs<FunctionProtoType>();
+}
+
 /* If "method" is overloaded, then return its name with the suffix
  * corresponding to the type of the final argument removed.
  * Otherwise, simply return the name of the function.
index 8195a36..2f8d88d 100644 (file)
@@ -75,6 +75,7 @@ public:
        static bool is_string(QualType type);
        static bool is_static(const isl_class &clazz, FunctionDecl *method);
        static string extract_type(QualType type);
+       static const FunctionProtoType *extract_prototype(QualType type);
 };
 
 #endif /* ISL_INTERFACE_GENERATOR_H */
index e6bdc75..11c18b5 100644 (file)
@@ -5523,6 +5523,15 @@ class val(object):
         ctx = Context.getDefaultInstance()
         res = isl.isl_val_one(ctx)
         return val(ctx=ctx, ptr=res)
+    def pow2(arg0):
+        try:
+            if not arg0.__class__ is val:
+                arg0 = val(arg0)
+        except:
+            raise
+        ctx = arg0.ctx
+        res = isl.isl_val_pow2(isl.isl_val_copy(arg0.ptr))
+        return val(ctx=ctx, ptr=res)
     def sgn(arg0):
         try:
             if not arg0.__class__ is val:
@@ -5640,6 +5649,8 @@ isl.isl_val_negone.restype = c_void_p
 isl.isl_val_negone.argtypes = [Context]
 isl.isl_val_one.restype = c_void_p
 isl.isl_val_one.argtypes = [Context]
+isl.isl_val_pow2.restype = c_void_p
+isl.isl_val_pow2.argtypes = [c_void_p]
 isl.isl_val_sgn.argtypes = [c_void_p]
 isl.isl_val_sub.restype = c_void_p
 isl.isl_val_sub.argtypes = [c_void_p, c_void_p]
index 33a96c2..7e6fd18 100644 (file)
@@ -126,8 +126,8 @@ void python_generator::print_copy(QualType type)
  */
 void python_generator::print_callback(ParmVarDecl *param, int arg)
 {
-       QualType type = param->getOriginalType()->getPointeeType();
-       const FunctionProtoType *fn = type->getAs<FunctionProtoType>();
+       QualType type = param->getOriginalType();
+       const FunctionProtoType *fn = extract_prototype(type);
        unsigned n_arg = fn->getNumArgs();
 
        printf("        exc_info = [None]\n");
index 5175b89..1dcc9f2 100644 (file)
@@ -21,6 +21,7 @@
 #include <isl/union_set.h>
 #include <isl/union_map.h>
 #include <isl/schedule_node.h>
+#include <isl/options.h>
 #include <isl_sort.h>
 #include <isl_tarjan.h>
 #include <isl_ast_private.h>
 #include <isl_ast_build_private.h>
 #include <isl_ast_graft_private.h>
 
+/* Try and reduce the number of disjuncts in the representation of "set",
+ * without dropping explicit representations of local variables.
+ */
+static __isl_give isl_set *isl_set_coalesce_preserve(__isl_take isl_set *set)
+{
+       isl_ctx *ctx;
+       int save_preserve;
+
+       if (!set)
+               return NULL;
+
+       ctx = isl_set_get_ctx(set);
+       save_preserve = isl_options_get_coalesce_preserve_locals(ctx);
+       isl_options_set_coalesce_preserve_locals(ctx, 1);
+       set = isl_set_coalesce(set);
+       isl_options_set_coalesce_preserve_locals(ctx, save_preserve);
+       return set;
+}
+
 /* Data used in generate_domain.
  *
  * "build" is the input build.
@@ -144,7 +164,7 @@ static isl_stat add_domain(__isl_take isl_map *executed,
 
        guard = isl_map_domain(isl_map_copy(map));
        guard = isl_set_compute_divs(guard);
-       guard = isl_set_coalesce(guard);
+       guard = isl_set_coalesce_preserve(guard);
        guard = isl_set_gist(guard, isl_ast_build_get_generated(build));
        guard = isl_ast_build_specialize(build, guard);
 
@@ -2841,7 +2861,7 @@ static __isl_give isl_set *compute_atomic_domain(
        }
 
        domain = isl_ast_build_eliminate(domains->build, domain);
-       domain = isl_set_coalesce(domain);
+       domain = isl_set_coalesce_preserve(domain);
        bset = isl_set_unshifted_simple_hull(domain);
        domain = isl_set_from_basic_set(bset);
        atomic_domain = isl_set_copy(domain);
@@ -2959,7 +2979,7 @@ static isl_stat compute_partial_domains(struct isl_codegen_domains *domains,
        domain = isl_ast_build_eliminate(domains->build, domain);
        domain = isl_set_intersect(domain, isl_set_copy(class_domain));
 
-       domain = isl_set_coalesce(domain);
+       domain = isl_set_coalesce_preserve(domain);
        domain = isl_set_make_disjoint(domain);
 
        list = isl_basic_set_list_from_set(domain);
@@ -3316,7 +3336,7 @@ static __isl_give isl_ast_graft_list *generate_shifted_component_tree_base(
                                                                build);
 
        domain = isl_ast_build_eliminate(build, domain);
-       domain = isl_set_coalesce(domain);
+       domain = isl_set_coalesce_preserve(domain);
 
        outer_disjunction = has_pure_outer_disjunction(domain, build);
        if (outer_disjunction < 0)
index 922c47f..1f96b7b 100644 (file)
@@ -3684,12 +3684,20 @@ static enum isl_change check_coalesce_eq(int i, int j,
  * an obvious subset of the other or if the extra integer divisions
  * of one basic map can be simplified away using the extra equalities
  * of the other basic map.
+ *
+ * Note that trying to coalesce pairs of disjuncts with the same
+ * number, but different local variables may drop the explicit
+ * representation of some of these local variables.
+ * This operation is therefore not performed when
+ * the "coalesce_preserve_locals" option is set.
  */
 static enum isl_change coalesce_pair(int i, int j,
        struct isl_coalesce_info *info)
 {
+       int preserve;
        isl_bool same;
        enum isl_change change;
+       isl_ctx *ctx;
 
        if (harmonize_divs(&info[i], &info[j]) < 0)
                return isl_change_error;
@@ -3699,7 +3707,9 @@ static enum isl_change coalesce_pair(int i, int j,
        if (same)
                return coalesce_local_pair(i, j, info);
 
-       if (info[i].bmap->n_div == info[j].bmap->n_div) {
+       ctx = isl_basic_map_get_ctx(info[i].bmap);
+       preserve = isl_options_get_coalesce_preserve_locals(ctx);
+       if (!preserve && info[i].bmap->n_div == info[j].bmap->n_div) {
                change = coalesce_local_pair(i, j, info);
                if (change != isl_change_none)
                        return change;
index 40718b1..592a20b 100644 (file)
@@ -3878,7 +3878,7 @@ __isl_give isl_basic_map *isl_basic_map_insert_dims(
        unsigned pos, unsigned n)
 {
        isl_bool rational;
-       isl_space *res_dim;
+       isl_space *res_space;
        struct isl_basic_map *res;
        struct isl_dim_map *dim_map;
        unsigned total, off;
@@ -3887,10 +3887,10 @@ __isl_give isl_basic_map *isl_basic_map_insert_dims(
        if (n == 0)
                return basic_map_space_reset(bmap, type);
 
-       if (!bmap)
-               return NULL;
-
-       res_dim = isl_space_insert_dims(isl_basic_map_get_space(bmap), type, pos, n);
+       res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap),
+                                       type, pos, n);
+       if (!res_space)
+               return isl_basic_map_free(bmap);
 
        total = isl_basic_map_total_dim(bmap) + n;
        dim_map = isl_dim_map_alloc(bmap->ctx, total);
@@ -3905,11 +3905,11 @@ __isl_give isl_basic_map *isl_basic_map_insert_dims(
                        isl_dim_map_dim_range(dim_map, bmap->dim, t,
                                                pos, size - pos, off + pos + n);
                }
-               off += isl_space_dim(res_dim, t);
+               off += isl_space_dim(res_space, t);
        }
        isl_dim_map_div(dim_map, bmap, off);
 
-       res = isl_basic_map_alloc_space(res_dim,
+       res = isl_basic_map_alloc_space(res_space,
                        bmap->n_div, bmap->n_eq, bmap->n_ineq);
        rational = isl_basic_map_is_rational(bmap);
        if (rational < 0)
index 06806d9..f794556 100644 (file)
@@ -3057,10 +3057,10 @@ __isl_give isl_basic_map *isl_basic_map_gist(__isl_take isl_basic_map *bmap,
 
        bmap = isl_basic_map_remove_redundancies(bmap);
        context = isl_basic_map_remove_redundancies(context);
+       context = isl_basic_map_align_divs(context, bmap);
        if (!context)
                goto error;
 
-       context = isl_basic_map_align_divs(context, bmap);
        n_div = isl_basic_map_dim(context, isl_dim_div);
        total = isl_basic_map_dim(bmap, isl_dim_all);
        extra = n_div - isl_basic_map_dim(bmap, isl_dim_div);
index eb3dd02..ea8fe78 100644 (file)
@@ -134,6 +134,9 @@ ISL_ARG_CHOICE(struct isl_options, convex, 0, "convex-hull", \
        convex, ISL_CONVEX_HULL_WRAP, "convex hull algorithm to use")
 ISL_ARG_BOOL(struct isl_options, coalesce_bounded_wrapping, 0,
        "coalesce-bounded-wrapping", 1, "bound wrapping during coalescing")
+ISL_ARG_BOOL(struct isl_options, coalesce_preserve_locals, 0,
+       "coalesce-preserve-locals", 0,
+       "preserve local variables during coalescing")
 ISL_ARG_INT(struct isl_options, schedule_max_coefficient, 0,
        "schedule-max-coefficient", "limit", -1, "Only consider schedules "
        "where the coefficients of the variable and parameter dimensions "
@@ -242,6 +245,11 @@ ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
        coalesce_bounded_wrapping)
 
 ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
+       coalesce_preserve_locals)
+ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
+       coalesce_preserve_locals)
+
+ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
        gbr_only_first)
 ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args,
        gbr_only_first)
index 13f21a7..3a59d2a 100644 (file)
@@ -34,6 +34,7 @@ struct isl_options {
        int                     convex;
 
        int                     coalesce_bounded_wrapping;
+       int                     coalesce_preserve_locals;
 
        int                     schedule_max_coefficient;
        int                     schedule_max_constant_term;
index 2a83e80..3a6c2bd 100644 (file)
@@ -1019,76 +1019,85 @@ static int valid_dim_type(enum isl_dim_type type)
  * If we are inserting parameters, then they are also inserted in
  * any nested spaces.
  */
-__isl_give isl_space *isl_space_insert_dims(__isl_take isl_space *dim,
+__isl_give isl_space *isl_space_insert_dims(__isl_take isl_space *space,
        enum isl_dim_type type, unsigned pos, unsigned n)
 {
+       isl_ctx *ctx;
        isl_id **ids = NULL;
+       unsigned total;
 
-       if (!dim)
+       if (!space)
                return NULL;
        if (n == 0)
-               return isl_space_reset(dim, type);
+               return isl_space_reset(space, type);
 
+       ctx = isl_space_get_ctx(space);
        if (!valid_dim_type(type))
-               isl_die(dim->ctx, isl_error_invalid,
+               isl_die(ctx, isl_error_invalid,
                        "cannot insert dimensions of specified type",
                        goto error);
 
-       isl_assert(dim->ctx, pos <= isl_space_dim(dim, type), goto error);
+       total = isl_space_dim(space, isl_dim_all);
+       if (total + n < total)
+               isl_die(ctx, isl_error_invalid,
+                       "overflow in total number of dimensions",
+                       return isl_space_free(space));
+       isl_assert(ctx, pos <= isl_space_dim(space, type), goto error);
 
-       dim = isl_space_cow(dim);
-       if (!dim)
+       space = isl_space_cow(space);
+       if (!space)
                return NULL;
 
-       if (dim->ids) {
+       if (space->ids) {
                enum isl_dim_type t, o = isl_dim_param;
                int off;
                int s[3];
-               ids = isl_calloc_array(dim->ctx, isl_id *,
-                                    dim->nparam + dim->n_in + dim->n_out + n);
+               ids = isl_calloc_array(ctx, isl_id *,
+                            space->nparam + space->n_in + space->n_out + n);
                if (!ids)
                        goto error;
                off = 0;
-               s[isl_dim_param - o] = dim->nparam;
-               s[isl_dim_in - o] = dim->n_in;
-               s[isl_dim_out - o] = dim->n_out;
+               s[isl_dim_param - o] = space->nparam;
+               s[isl_dim_in - o] = space->n_in;
+               s[isl_dim_out - o] = space->n_out;
                for (t = isl_dim_param; t <= isl_dim_out; ++t) {
                        if (t != type) {
-                               get_ids(dim, t, 0, s[t - o], ids + off);
+                               get_ids(space, t, 0, s[t - o], ids + off);
                                off += s[t - o];
                        } else {
-                               get_ids(dim, t, 0, pos, ids + off);
+                               get_ids(space, t, 0, pos, ids + off);
                                off += pos + n;
-                               get_ids(dim, t, pos, s[t - o] - pos, ids + off);
+                               get_ids(space, t, pos, s[t - o] - pos,
+                                       ids + off);
                                off += s[t - o] - pos;
                        }
                }
-               free(dim->ids);
-               dim->ids = ids;
-               dim->n_id = dim->nparam + dim->n_in + dim->n_out + n;
+               free(space->ids);
+               space->ids = ids;
+               space->n_id = space->nparam + space->n_in + space->n_out + n;
        }
        switch (type) {
-       case isl_dim_param:     dim->nparam += n; break;
-       case isl_dim_in:        dim->n_in += n; break;
-       case isl_dim_out:       dim->n_out += n; break;
+       case isl_dim_param:     space->nparam += n; break;
+       case isl_dim_in:        space->n_in += n; break;
+       case isl_dim_out:       space->n_out += n; break;
        default:                ;
        }
-       dim = isl_space_reset(dim, type);
+       space = isl_space_reset(space, type);
 
        if (type == isl_dim_param) {
-               if (dim && dim->nested[0] &&
-                   !(dim->nested[0] = isl_space_insert_dims(dim->nested[0],
+               if (space && space->nested[0] &&
+                   !(space->nested[0] = isl_space_insert_dims(space->nested[0],
                                                    isl_dim_param, pos, n)))
                        goto error;
-               if (dim && dim->nested[1] &&
-                   !(dim->nested[1] = isl_space_insert_dims(dim->nested[1],
+               if (space && space->nested[1] &&
+                   !(space->nested[1] = isl_space_insert_dims(space->nested[1],
                                                    isl_dim_param, pos, n)))
                        goto error;
        }
 
-       return dim;
+       return space;
 error:
-       isl_space_free(dim);
+       isl_space_free(space);
        return NULL;
 }
 
index 5633620..d08870d 100644 (file)
@@ -679,7 +679,7 @@ struct {
 } val_un_tests[] = {
        { &isl_val_neg, "0", "0" },
        { &isl_val_abs, "0", "0" },
-       { &isl_val_2exp, "0", "1" },
+       { &isl_val_pow2, "0", "1" },
        { &isl_val_floor, "0", "0" },
        { &isl_val_ceil, "0", "0" },
        { &isl_val_neg, "1", "-1" },
@@ -710,11 +710,11 @@ struct {
        { &isl_val_ceil, "infty", "infty" },
        { &isl_val_ceil, "-infty", "-infty" },
        { &isl_val_ceil, "NaN", "NaN" },
-       { &isl_val_2exp, "-3", "1/8" },
-       { &isl_val_2exp, "-1", "1/2" },
-       { &isl_val_2exp, "1", "2" },
-       { &isl_val_2exp, "2", "4" },
-       { &isl_val_2exp, "3", "8" },
+       { &isl_val_pow2, "-3", "1/8" },
+       { &isl_val_pow2, "-1", "1/2" },
+       { &isl_val_pow2, "1", "2" },
+       { &isl_val_pow2, "2", "4" },
+       { &isl_val_pow2, "3", "8" },
        { &isl_val_inv, "1", "1" },
        { &isl_val_inv, "2", "1/2" },
        { &isl_val_inv, "1/2", "2" },
@@ -1599,6 +1599,49 @@ static int test_plain_gist(isl_ctx *ctx)
        return 0;
 }
 
+/* Inputs for isl_basic_set_gist tests that are expected to fail.
+ */
+struct {
+       const char *set;
+       const char *context;
+} gist_fail_tests[] = {
+       { "{ [i] : exists (e0, e1: 3e1 >= 1 + 2e0 and "
+           "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }",
+         "{ [i] : i >= 0 }" },
+};
+
+/* Check that isl_basic_set_gist fails (gracefully) when expected.
+ * In particular, the user should be able to recover from the failure.
+ */
+static isl_stat test_gist_fail(struct isl_ctx *ctx)
+{
+       int i, n;
+       int on_error;
+
+       on_error = isl_options_get_on_error(ctx);
+       isl_options_set_on_error(ctx, ISL_ON_ERROR_CONTINUE);
+       n = ARRAY_SIZE(gist_fail_tests);
+       for (i = 0; i < n; ++i) {
+               const char *str;
+               isl_basic_set *bset, *context;
+
+               bset = isl_basic_set_read_from_str(ctx, gist_fail_tests[i].set);
+               str = gist_fail_tests[i].context;
+               context = isl_basic_set_read_from_str(ctx, str);
+               bset = isl_basic_set_gist(bset, context);
+               isl_basic_set_free(bset);
+               if (bset)
+                       break;
+       }
+       isl_options_set_on_error(ctx, on_error);
+       if (i < n)
+               isl_die(ctx, isl_error_unknown,
+                       "operation not expected to succeed",
+                       return isl_stat_error);
+
+       return isl_stat_ok;
+}
+
 struct {
        const char *set;
        const char *context;
@@ -1724,6 +1767,9 @@ static int test_gist(struct isl_ctx *ctx)
                                "inconsistent gist test case", return -1);
        }
 
+       if (test_gist_fail(ctx) < 0)
+               return -1;
+
        test_gist_case(ctx, "gist1");
 
        str = "[p0, p2, p3, p5, p6, p10] -> { [] : "
index 7a37d18..06e2874 100644 (file)
@@ -528,7 +528,7 @@ __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v)
 
 /* Return 2^v, where v is an integer (that is not too large).
  */
-__isl_give isl_val *isl_val_2exp(__isl_take isl_val *v)
+__isl_give isl_val *isl_val_pow2(__isl_take isl_val *v)
 {
        unsigned long exp;
        int neg;
@@ -557,6 +557,13 @@ __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v)
        return v;
 }
 
+/* This is an alternative name for the function above.
+ */
+__isl_give isl_val *isl_val_2exp(__isl_take isl_val *v)
+{
+       return isl_val_pow2(v);
+}
+
 /* Return the minimum of "v1" and "v2".
  */
 __isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2)