Index: include/polly/Support/SCEVAffinator.h
===================================================================
--- include/polly/Support/SCEVAffinator.h
+++ include/polly/Support/SCEVAffinator.h
@@ -17,20 +17,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
 
-#include "isl/ctx.h"
-
-struct isl_ctx;
-struct isl_map;
-struct isl_basic_map;
-struct isl_id;
-struct isl_set;
-struct isl_union_set;
-struct isl_union_map;
-struct isl_space;
-struct isl_ast_build;
-struct isl_constraint;
-struct isl_pw_aff;
-struct isl_schedule;
+#include "isl/isl-noexceptions.h"
 
 namespace llvm {
 class Region;
@@ -47,13 +34,12 @@
 ///
 /// The first element of the pair is the isl representation of the SCEV, the
 /// second is the domain under which it is __invalid__.
-typedef std::pair<isl_pw_aff *, isl_set *> PWACtx;
+typedef std::pair<isl::pw_aff, isl::set> PWACtx;
 
 /// Translate a SCEV to an isl_pw_aff and the domain on which it is invalid.
 struct SCEVAffinator : public llvm::SCEVVisitor<SCEVAffinator, PWACtx> {
 public:
   SCEVAffinator(Scop *S, llvm::LoopInfo &LI);
-  ~SCEVAffinator();
 
   /// Translate a SCEV to an isl_pw_aff.
   ///
@@ -84,7 +70,7 @@
   llvm::DenseMap<CacheKey, PWACtx> CachedExpressions;
 
   Scop *S;
-  isl_ctx *Ctx;
+  isl::ctx Ctx;
   unsigned NumIterators;
   llvm::ScalarEvolution &SE;
   llvm::LoopInfo &LI;
@@ -97,7 +83,7 @@
   llvm::Loop *getScope();
 
   /// Return a PWACtx for @p PWA that is always valid.
-  __isl_give PWACtx getPWACtxFromPWA(__isl_take isl_pw_aff *PWA);
+  __isl_give PWACtx getPWACtxFromPWA(__isl_take isl::pw_aff PWA);
 
   /// Compute the non-wrapping version of @p PWA for type @p ExprType.
   ///
@@ -105,7 +91,7 @@
   /// @param Type The type of the SCEV that was translated to @p PWA.
   ///
   /// @returns The expr @p PWA modulo the size constraints of @p ExprType.
-  __isl_give isl_pw_aff *addModuloSemantic(__isl_take isl_pw_aff *PWA,
+  __isl_give isl::pw_aff addModuloSemantic(__isl_take isl::pw_aff PWA,
                                            llvm::Type *ExprType) const;
 
   /// If @p Expr might cause an integer wrap record an assumption.
Index: lib/Analysis/ScopInfo.cpp
===================================================================
--- lib/Analysis/ScopInfo.cpp
+++ lib/Analysis/ScopInfo.cpp
@@ -1105,9 +1105,9 @@
   PWACtx PWAC = Stmt->getParent()->getPwAff(E, Stmt->getEntryBlock());
   isl::set StmtDom = getStatement()->getDomain();
   StmtDom = StmtDom.reset_tuple_id();
-  isl::set NewInvalidDom = StmtDom.intersect(isl::manage(PWAC.second));
+  isl::set NewInvalidDom = StmtDom.intersect(PWAC.second);
   InvalidDomain = InvalidDomain.unite(NewInvalidDom);
-  return isl::manage(PWAC.first);
+  return PWAC.first;
 }
 
 // Create a map in the size of the provided set domain, that maps from the
@@ -1440,8 +1440,8 @@
          DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, const SCEV *E,
          bool NonNegative = false) {
   PWACtx PWAC = S.getPwAff(E, BB, NonNegative);
-  InvalidDomainMap[BB] = InvalidDomainMap[BB].unite(isl::manage(PWAC.second));
-  return PWAC.first;
+  InvalidDomainMap[BB] = InvalidDomainMap[BB].unite(PWAC.second);
+  return PWAC.first.take();
 }
 
 /// Build the conditions sets for the switch @p SI in the @p Domain.
@@ -4493,8 +4493,7 @@
 
 isl::pw_aff Scop::getPwAffOnly(const SCEV *E, BasicBlock *BB) {
   PWACtx PWAC = getPwAff(E, BB);
-  isl_set_free(PWAC.second);
-  return isl::manage(PWAC.first);
+  return PWAC.first;
 }
 
 isl::union_map
Index: lib/Support/SCEVAffinator.cpp
===================================================================
--- lib/Support/SCEVAffinator.cpp
+++ lib/Support/SCEVAffinator.cpp
@@ -50,27 +50,12 @@
   return isl_stat_ok;
 }
 
-/// Helper to free a PWACtx object.
-static void freePWACtx(__isl_take PWACtx &PWAC) {
-  isl_pw_aff_free(PWAC.first);
-  isl_set_free(PWAC.second);
-}
-
-/// Helper to copy a PWACtx object.
-static __isl_give PWACtx copyPWACtx(const __isl_keep PWACtx &PWAC) {
-  return std::make_pair(isl_pw_aff_copy(PWAC.first), isl_set_copy(PWAC.second));
-}
-
 /// Determine if @p PWAC is too complex to continue.
-///
-/// Note that @p PWAC will be "free" (deallocated) if this function returns
-/// true, but not if this function returns false.
-static bool isTooComplex(PWACtx &PWAC) {
+static bool isTooComplex(PWACtx PWAC) {
   unsigned NumBasicSets = 0;
-  isl_pw_aff_foreach_piece(PWAC.first, addNumBasicSets, &NumBasicSets);
+  isl_pw_aff_foreach_piece(PWAC.first.keep(), addNumBasicSets, &NumBasicSets);
   if (NumBasicSets <= MaxDisjunctionsInPwAff)
     return false;
-  freePWACtx(PWAC);
   return true;
 }
 
@@ -81,10 +66,12 @@
   return SCEV::NoWrapMask;
 }
 
-static void combine(__isl_keep PWACtx &PWAC0, const __isl_take PWACtx &PWAC1,
-                    isl_pw_aff *(Fn)(isl_pw_aff *, isl_pw_aff *)) {
-  PWAC0.first = Fn(PWAC0.first, PWAC1.first);
-  PWAC0.second = isl_set_union(PWAC0.second, PWAC1.second);
+static PWACtx combine(PWACtx PWAC0, PWACtx PWAC1,
+                      __isl_give isl_pw_aff *(Fn)(__isl_take isl_pw_aff *,
+                                                  __isl_take isl_pw_aff *)) {
+  PWAC0.first = isl::manage(Fn(PWAC0.first.take(), PWAC1.first.take()));
+  PWAC0.second = PWAC0.second.unite(PWAC1.second);
+  return PWAC0;
 }
 
 static __isl_give isl_pw_aff *getWidthExpValOnDomain(unsigned Width,
@@ -99,36 +86,30 @@
     : S(S), Ctx(S->getIslCtx().get()), SE(*S->getSE()), LI(LI),
       TD(S->getFunction().getParent()->getDataLayout()) {}
 
-SCEVAffinator::~SCEVAffinator() {
-  for (auto &CachedPair : CachedExpressions)
-    freePWACtx(CachedPair.second);
-}
-
 Loop *SCEVAffinator::getScope() { return BB ? LI.getLoopFor(BB) : nullptr; }
 
-void SCEVAffinator::interpretAsUnsigned(__isl_keep PWACtx &PWAC,
-                                        unsigned Width) {
-  auto *PWA = PWAC.first;
-  auto *NonNegDom = isl_pw_aff_nonneg_set(isl_pw_aff_copy(PWA));
-  auto *NonNegPWA = isl_pw_aff_intersect_domain(isl_pw_aff_copy(PWA),
-                                                isl_set_copy(NonNegDom));
+void SCEVAffinator::interpretAsUnsigned(PWACtx &PWAC, unsigned Width) {
+  auto *NonNegDom = isl_pw_aff_nonneg_set(PWAC.first.copy());
+  auto *NonNegPWA =
+      isl_pw_aff_intersect_domain(PWAC.first.copy(), isl_set_copy(NonNegDom));
   auto *ExpPWA = getWidthExpValOnDomain(Width, isl_set_complement(NonNegDom));
-  PWAC.first = isl_pw_aff_union_add(NonNegPWA, isl_pw_aff_add(PWA, ExpPWA));
+  PWAC.first = isl::manage(isl_pw_aff_union_add(
+      NonNegPWA, isl_pw_aff_add(PWAC.first.take(), ExpPWA)));
 }
 
 void SCEVAffinator::takeNonNegativeAssumption(PWACtx &PWAC) {
-  auto *NegPWA = isl_pw_aff_neg(isl_pw_aff_copy(PWAC.first));
+  auto *NegPWA = isl_pw_aff_neg(PWAC.first.copy());
   auto *NegDom = isl_pw_aff_pos_set(NegPWA);
-  PWAC.second = isl_set_union(PWAC.second, isl_set_copy(NegDom));
+  PWAC.second =
+      isl::manage(isl_set_union(PWAC.second.take(), isl_set_copy(NegDom)));
   auto *Restriction = BB ? NegDom : isl_set_params(NegDom);
   auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
   S->recordAssumption(UNSIGNED, isl::manage(Restriction), DL, AS_RESTRICTION,
                       BB);
 }
 
-__isl_give PWACtx SCEVAffinator::getPWACtxFromPWA(__isl_take isl_pw_aff *PWA) {
-  return std::make_pair(
-      PWA, isl_set_empty(isl_space_set_alloc(Ctx, 0, NumIterators)));
+PWACtx SCEVAffinator::getPWACtxFromPWA(isl::pw_aff PWA) {
+  return std::make_pair(PWA, isl::set::empty(isl::space(Ctx, 0, NumIterators)));
 }
 
 __isl_give PWACtx SCEVAffinator::getPwAff(const SCEV *Expr, BasicBlock *BB) {
@@ -144,8 +125,7 @@
   return visit(Expr);
 }
 
-__isl_give PWACtx SCEVAffinator::checkForWrapping(const SCEV *Expr,
-                                                  PWACtx PWAC) const {
+PWACtx SCEVAffinator::checkForWrapping(const SCEV *Expr, PWACtx PWAC) const {
   // If the SCEV flags do contain NSW (no signed wrap) then PWA already
   // represents Expr in modulo semantic (it is not allowed to overflow), thus we
   // are done. Otherwise, we will compute:
@@ -156,42 +136,33 @@
   if (IgnoreIntegerWrapping || (getNoWrapFlags(Expr) & SCEV::FlagNSW))
     return PWAC;
 
-  auto *PWA = PWAC.first;
-  auto *PWAMod = addModuloSemantic(isl_pw_aff_copy(PWA), Expr->getType());
-  auto *NotEqualSet = isl_pw_aff_ne_set(isl_pw_aff_copy(PWA), PWAMod);
-  PWAC.second = isl_set_union(PWAC.second, isl_set_copy(NotEqualSet));
-  PWAC.second = isl_set_coalesce(PWAC.second);
+  isl::pw_aff PWAMod = addModuloSemantic(PWAC.first, Expr->getType());
+
+  isl::set NotEqualSet = PWAC.first.ne_set(PWAMod);
+  PWAC.second = PWAC.second.unite(NotEqualSet).coalesce();
 
   const DebugLoc &Loc = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
-  NotEqualSet = BB ? NotEqualSet : isl_set_params(NotEqualSet);
-  NotEqualSet = isl_set_coalesce(NotEqualSet);
+  if (!BB)
+    NotEqualSet = NotEqualSet.params();
+  NotEqualSet = NotEqualSet.coalesce();
 
-  if (isl_set_is_empty(NotEqualSet))
-    isl_set_free(NotEqualSet);
-  else
-    S->recordAssumption(WRAPPING, isl::manage(NotEqualSet), Loc, AS_RESTRICTION,
-                        BB);
+  if (!NotEqualSet.is_empty())
+    S->recordAssumption(WRAPPING, NotEqualSet, Loc, AS_RESTRICTION, BB);
 
   return PWAC;
 }
 
-__isl_give isl_pw_aff *
-SCEVAffinator::addModuloSemantic(__isl_take isl_pw_aff *PWA,
-                                 Type *ExprType) const {
+isl::pw_aff SCEVAffinator::addModuloSemantic(isl::pw_aff PWA,
+                                             Type *ExprType) const {
   unsigned Width = TD.getTypeSizeInBits(ExprType);
-  isl_ctx *Ctx = isl_pw_aff_get_ctx(PWA);
-
-  isl_val *ModVal = isl_val_int_from_ui(Ctx, Width);
-  ModVal = isl_val_2exp(ModVal);
-
-  isl_set *Domain = isl_pw_aff_domain(isl_pw_aff_copy(PWA));
-  isl_pw_aff *AddPW = getWidthExpValOnDomain(Width - 1, Domain);
 
-  PWA = isl_pw_aff_add(PWA, isl_pw_aff_copy(AddPW));
-  PWA = isl_pw_aff_mod_val(PWA, ModVal);
-  PWA = isl_pw_aff_sub(PWA, AddPW);
+  auto ModVal = isl::val::int_from_ui(Ctx, Width);
+  ModVal = ModVal.two_exp();
 
-  return PWA;
+  isl::set Domain = PWA.domain();
+  isl::pw_aff AddPW =
+      isl::manage(getWidthExpValOnDomain(Width - 1, Domain.take()));
+  return PWA.add(AddPW).mod(ModVal).sub(AddPW);
 }
 
 bool SCEVAffinator::hasNSWAddRecForLoop(Loop *L) const {
@@ -217,12 +188,12 @@
   return Width <= MaxSmallBitWidth;
 }
 
-__isl_give PWACtx SCEVAffinator::visit(const SCEV *Expr) {
+PWACtx SCEVAffinator::visit(const SCEV *Expr) {
 
   auto Key = std::make_pair(Expr, BB);
   PWACtx PWAC = CachedExpressions[Key];
   if (PWAC.first)
-    return copyPWACtx(PWAC);
+    return PWAC;
 
   auto ConstantAndLeftOverPair = extractConstantFactor(Expr, SE);
   auto *Factor = ConstantAndLeftOverPair.first;
@@ -236,14 +207,14 @@
   // to treat subexpressions that we cannot translate into an piecewise affine
   // expression, as constant parameters of the piecewise affine expression.
   if (isl_id *Id = S->getIdForParam(Expr).release()) {
-    isl_space *Space = isl_space_set_alloc(Ctx, 1, NumIterators);
+    isl_space *Space = isl_space_set_alloc(Ctx.get(), 1, NumIterators);
     Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
 
     isl_set *Domain = isl_set_universe(isl_space_copy(Space));
     isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space));
     Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
 
-    PWAC = getPWACtxFromPWA(isl_pw_aff_alloc(Domain, Affine));
+    PWAC = getPWACtxFromPWA(isl::manage(isl_pw_aff_alloc(Domain, Affine)));
   } else {
     PWAC = SCEVVisitor<SCEVAffinator, PWACtx>::visit(Expr);
     if (computeModuloForExpr(Expr))
@@ -253,18 +224,18 @@
   }
 
   if (!Factor->getType()->isIntegerTy(1)) {
-    combine(PWAC, visitConstant(Factor), isl_pw_aff_mul);
+    PWAC = combine(PWAC, visitConstant(Factor), isl_pw_aff_mul);
     if (computeModuloForExpr(Key.first))
       PWAC.first = addModuloSemantic(PWAC.first, Expr->getType());
   }
 
   // For compile time reasons we need to simplify the PWAC before we cache and
   // return it.
-  PWAC.first = isl_pw_aff_coalesce(PWAC.first);
+  PWAC.first = PWAC.first.coalesce();
   if (!computeModuloForExpr(Key.first))
     PWAC = checkForWrapping(Key.first, PWAC);
 
-  CachedExpressions[Key] = copyPWACtx(PWAC);
+  CachedExpressions[Key] = PWAC;
   return PWAC;
 }
 
@@ -282,11 +253,12 @@
   //    demand.
   // 2. We pass down the signedness of the calculation and use it to interpret
   //    this constant correctly.
-  v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
+  v = isl_valFromAPInt(Ctx.get(), Value->getValue(), /* isSigned */ true);
 
-  isl_space *Space = isl_space_set_alloc(Ctx, 0, NumIterators);
+  isl_space *Space = isl_space_set_alloc(Ctx.get(), 0, NumIterators);
   isl_local_space *ls = isl_local_space_from_space(Space);
-  return getPWACtxFromPWA(isl_pw_aff_from_aff(isl_aff_val_on_domain(ls, v)));
+  return getPWACtxFromPWA(
+      isl::manage(isl_pw_aff_from_aff(isl_aff_val_on_domain(ls, v))));
 }
 
 __isl_give PWACtx
@@ -304,14 +276,15 @@
   if (computeModuloForExpr(Expr))
     return OpPWAC;
 
-  auto *Dom = isl_pw_aff_domain(isl_pw_aff_copy(OpPWAC.first));
+  auto *Dom = OpPWAC.first.domain().take();
   auto *ExpPWA = getWidthExpValOnDomain(Width - 1, Dom);
   auto *GreaterDom =
-      isl_pw_aff_ge_set(isl_pw_aff_copy(OpPWAC.first), isl_pw_aff_copy(ExpPWA));
+      isl_pw_aff_ge_set(OpPWAC.first.copy(), isl_pw_aff_copy(ExpPWA));
   auto *SmallerDom =
-      isl_pw_aff_lt_set(isl_pw_aff_copy(OpPWAC.first), isl_pw_aff_neg(ExpPWA));
+      isl_pw_aff_lt_set(OpPWAC.first.copy(), isl_pw_aff_neg(ExpPWA));
   auto *OutOfBoundsDom = isl_set_union(SmallerDom, GreaterDom);
-  OpPWAC.second = isl_set_union(OpPWAC.second, isl_set_copy(OutOfBoundsDom));
+  OpPWAC.second =
+      OpPWAC.second.unite(isl::manage(isl_set_copy(OutOfBoundsDom)));
 
   if (!BB) {
     assert(isl_set_dim(OutOfBoundsDom, isl_dim_set) == 0 &&
@@ -386,17 +359,16 @@
   return OpPWAC;
 }
 
-__isl_give PWACtx
-SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+PWACtx SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
   // As all values are represented as signed, a sign extension is a noop.
   return visit(Expr->getOperand());
 }
 
-__isl_give PWACtx SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
+PWACtx SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
   PWACtx Sum = visit(Expr->getOperand(0));
 
   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
-    combine(Sum, visit(Expr->getOperand(i)), isl_pw_aff_add);
+    Sum = combine(Sum, visit(Expr->getOperand(i)), isl_pw_aff_add);
     if (isTooComplex(Sum))
       return std::make_pair(nullptr, nullptr);
   }
@@ -408,7 +380,7 @@
   PWACtx Prod = visit(Expr->getOperand(0));
 
   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
-    combine(Prod, visit(Expr->getOperand(i)), isl_pw_aff_mul);
+    Prod = combine(Prod, visit(Expr->getOperand(i)), isl_pw_aff_mul);
     if (isTooComplex(Prod))
       return std::make_pair(nullptr, nullptr);
   }
@@ -416,7 +388,7 @@
   return Prod;
 }
 
-__isl_give PWACtx SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+PWACtx SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
   assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
 
   auto Flags = Expr->getNoWrapFlags();
@@ -427,7 +399,7 @@
            "Scop does not contain the loop referenced in this AddRec");
 
     PWACtx Step = visit(Expr->getOperand(1));
-    isl_space *Space = isl_space_set_alloc(Ctx, 0, NumIterators);
+    isl_space *Space = isl_space_set_alloc(Ctx.get(), 0, NumIterators);
     isl_local_space *LocalSpace = isl_local_space_from_space(Space);
 
     unsigned loopDimension = S->getRelativeLoopDepth(Expr->getLoop());
@@ -436,7 +408,7 @@
         isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
     isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
 
-    Step.first = isl_pw_aff_mul(Step.first, LPwAff);
+    Step.first = Step.first.mul(isl::manage(LPwAff));
     return Step;
   }
 
@@ -451,7 +423,7 @@
 
   PWACtx Result = visit(ZeroStartExpr);
   PWACtx Start = visit(Expr->getStart());
-  combine(Result, Start, isl_pw_aff_add);
+  Result = combine(Result, Start, isl_pw_aff_add);
   return Result;
 }
 
@@ -459,7 +431,7 @@
   PWACtx Max = visit(Expr->getOperand(0));
 
   for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
-    combine(Max, visit(Expr->getOperand(i)), isl_pw_aff_max);
+    Max = combine(Max, visit(Expr->getOperand(i)), isl_pw_aff_max);
     if (isTooComplex(Max))
       return std::make_pair(nullptr, nullptr);
   }
@@ -492,9 +464,9 @@
     // piece-wise defined value described for zero-extends as we already know
     // the actual value of the constant divisor.
     unsigned Width = TD.getTypeSizeInBits(Expr->getType());
-    auto *DivisorDom = isl_pw_aff_domain(isl_pw_aff_copy(DivisorPWAC.first));
+    auto *DivisorDom = DivisorPWAC.first.domain().take();
     auto *WidthExpPWA = getWidthExpValOnDomain(Width, DivisorDom);
-    DivisorPWAC.first = isl_pw_aff_add(DivisorPWAC.first, WidthExpPWA);
+    DivisorPWAC.first = DivisorPWAC.first.add(isl::manage(WidthExpPWA));
   }
 
   // TODO: One can represent the dividend as piece-wise function to be more
@@ -503,8 +475,8 @@
   // Assume a non-negative dividend.
   takeNonNegativeAssumption(DividendPWAC);
 
-  combine(DividendPWAC, DivisorPWAC, isl_pw_aff_div);
-  DividendPWAC.first = isl_pw_aff_floor(DividendPWAC.first);
+  DividendPWAC = combine(DividendPWAC, DivisorPWAC, isl_pw_aff_div);
+  DividendPWAC.first = DividendPWAC.first.floor();
 
   return DividendPWAC;
 }
@@ -522,7 +494,7 @@
   auto *Dividend = SDiv->getOperand(0);
   auto *DividendSCEV = SE.getSCEVAtScope(Dividend, Scope);
   auto DividendPWAC = visit(DividendSCEV);
-  combine(DividendPWAC, DivisorPWAC, isl_pw_aff_tdiv_q);
+  DividendPWAC = combine(DividendPWAC, DivisorPWAC, isl_pw_aff_tdiv_q);
   return DividendPWAC;
 }
 
@@ -539,7 +511,7 @@
   auto *Dividend = SRem->getOperand(0);
   auto *DividendSCEV = SE.getSCEVAtScope(Dividend, Scope);
   auto DividendPWAC = visit(DividendSCEV);
-  combine(DividendPWAC, DivisorPWAC, isl_pw_aff_tdiv_r);
+  DividendPWAC = combine(DividendPWAC, DivisorPWAC, isl_pw_aff_tdiv_r);
   return DividendPWAC;
 }