[polly] r261100 - [Refactor] Move isl_ctx into Scop.

Hongbin Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 17 07:49:22 PST 2016


Author: ether
Date: Wed Feb 17 09:49:21 2016
New Revision: 261100

URL: http://llvm.org/viewvc/llvm-project?rev=261100&view=rev
Log:
[Refactor] Move isl_ctx into Scop.

  After we moved isl_ctx into Scop, we need to free the isl_ctx after
  freeing all isl objects, which requires the ScopInfo pass to be freed
  at last. But this is not guaranteed by the PassManager, and we need
  extra code to free the isl_ctx at the right time.

  We introduced a shared pointer to manage the isl_ctx, and distribute
  it to all analyses that create isl objects. As such, whenever we free
  an analyses with the shared_ptr (and also free the isl objects which
  are created by the analyses), we decrease the (shared) reference
  counter of the shared_ptr by 1. Whenever the reference counter reach
  0 in the releaseMemory function of an analysis, that analysis will
  be the last one that hold any isl objects, and we can safely free the
  isl_ctx with that analysis.

Differential Revision: http://reviews.llvm.org/D17241

Modified:
    polly/trunk/include/polly/DependenceInfo.h
    polly/trunk/include/polly/ScopInfo.h
    polly/trunk/lib/Analysis/DependenceInfo.cpp
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/lib/CodeGen/IslAst.cpp

Modified: polly/trunk/include/polly/DependenceInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/DependenceInfo.h?rev=261100&r1=261099&r2=261100&view=diff
==============================================================================
--- polly/trunk/include/polly/DependenceInfo.h (original)
+++ polly/trunk/include/polly/DependenceInfo.h Wed Feb 17 09:49:21 2016
@@ -137,15 +137,15 @@ struct Dependences {
   /// is able to call or modify a dependences struct.
   friend class DependenceInfo;
 
-private:
-  /// @brief Create an empty dependences struct.
-  Dependences()
-      : RAW(nullptr), WAR(nullptr), WAW(nullptr), RED(nullptr),
-        TC_RED(nullptr) {}
-
   /// @brief Destructor that will free internal objects.
   ~Dependences() { releaseMemory(); }
 
+private:
+  /// @brief Create an empty dependences struct.
+  explicit Dependences(const std::shared_ptr<isl_ctx> &IslCtx)
+      : RAW(nullptr), WAR(nullptr), WAW(nullptr), RED(nullptr), TC_RED(nullptr),
+        IslCtx(IslCtx) {}
+
   /// @brief Calculate and add at the privatization dependences.
   void addPrivatizationDependences();
 
@@ -173,6 +173,9 @@ private:
 
   /// @brief Mapping from memory accesses to their reduction dependences.
   ReductionDependencesMapTy ReductionDependences;
+
+  /// Isl context from the SCoP.
+  std::shared_ptr<isl_ctx> IslCtx;
 };
 
 class DependenceInfo : public ScopPass {
@@ -183,7 +186,7 @@ public:
   DependenceInfo() : ScopPass(ID) {}
 
   /// @brief Return the dependence information for the current SCoP.
-  const Dependences &getDependences() { return D; }
+  const Dependences &getDependences() { return *D; }
 
   /// @brief Recompute dependences from schedule and memory accesses.
   void recomputeDependences();
@@ -192,10 +195,10 @@ public:
   bool runOnScop(Scop &S) override;
 
   /// @brief Print the dependences for the given SCoP to @p OS.
-  void printScop(raw_ostream &OS, Scop &) const override { D.print(OS); }
+  void printScop(raw_ostream &OS, Scop &) const override { D->print(OS); }
 
   /// @brief Release the internal memory.
-  void releaseMemory() override { D.releaseMemory(); }
+  void releaseMemory() override { D.reset(); }
 
   /// @brief Register all analyses and transformation required.
   void getAnalysisUsage(AnalysisUsage &AU) const override;
@@ -204,7 +207,7 @@ private:
   Scop *S;
 
   /// @brief Dependences struct for the current SCoP.
-  Dependences D;
+  std::auto_ptr<Dependences> D;
 };
 
 } // End polly namespace.

Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=261100&r1=261099&r2=261100&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Wed Feb 17 09:49:21 2016
@@ -1273,7 +1273,13 @@ private:
   ParamIdType ParameterIds;
 
   /// Isl context.
-  isl_ctx *IslCtx;
+  ///
+  /// We need a shared_ptr with reference counter to delete the context when all
+  /// isl objects are deleted. We will distribute the shared_ptr to all objects
+  /// that use the context to create isl objects, and increase the reference
+  /// counter. By doing this, we guarantee that the context is deleted when we
+  /// delete the last object that creates isl objects with the context.
+  std::shared_ptr<isl_ctx> IslCtx;
 
   /// @brief A map from basic blocks to SCoP statements.
   DenseMap<BasicBlock *, ScopStmt *> StmtMap;
@@ -1376,7 +1382,7 @@ private:
   InvariantEquivClassesTy InvariantEquivClasses;
 
   /// @brief Scop constructor; invoked from ScopInfo::buildScop.
-  Scop(Region &R, ScalarEvolution &SE, isl_ctx *ctx, unsigned MaxLoopDepth);
+  Scop(Region &R, ScalarEvolution &SE, unsigned MaxLoopDepth);
 
   /// @brief Get or create the access function set in a BasicBlock
   AccFuncSetType &getOrCreateAccessFunctions(const BasicBlock *BB) {
@@ -1916,6 +1922,9 @@ public:
   /// @return The isl context of this static control part.
   isl_ctx *getIslCtx() const;
 
+  /// @brief Directly return the shared_ptr of the context.
+  const std::shared_ptr<isl_ctx> &getSharedIslCtx() const { return IslCtx; }
+
   /// @brief Compute the isl representation for the SCEV @p
   ///
   /// @param BB An (optional) basic block in which the isl_pw_aff is computed.
@@ -2015,7 +2024,6 @@ class ScopInfo : public RegionPass {
 
   // The Scop
   std::unique_ptr<Scop> scop;
-  isl_ctx *ctx;
 
   // Clear the context.
   void clear();

Modified: polly/trunk/lib/Analysis/DependenceInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/DependenceInfo.cpp?rev=261100&r1=261099&r2=261100&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/DependenceInfo.cpp (original)
+++ polly/trunk/lib/Analysis/DependenceInfo.cpp Wed Feb 17 09:49:21 2016
@@ -283,10 +283,10 @@ void Dependences::calculateDependences(S
   Write = isl_union_map_coalesce(Write);
   MayWrite = isl_union_map_coalesce(MayWrite);
 
-  long MaxOpsOld = isl_ctx_get_max_operations(S.getIslCtx());
+  long MaxOpsOld = isl_ctx_get_max_operations(IslCtx.get());
   if (OptComputeOut)
-    isl_ctx_set_max_operations(S.getIslCtx(), OptComputeOut);
-  isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_CONTINUE);
+    isl_ctx_set_max_operations(IslCtx.get(), OptComputeOut);
+  isl_options_set_on_error(IslCtx.get(), ISL_ON_ERROR_CONTINUE);
 
   DEBUG(dbgs() << "Read: " << Read << "\n";
         dbgs() << "Write: " << Write << "\n";
@@ -362,16 +362,16 @@ void Dependences::calculateDependences(S
   WAW = isl_union_map_coalesce(WAW);
   WAR = isl_union_map_coalesce(WAR);
 
-  if (isl_ctx_last_error(S.getIslCtx()) == isl_error_quota) {
+  if (isl_ctx_last_error(IslCtx.get()) == isl_error_quota) {
     isl_union_map_free(RAW);
     isl_union_map_free(WAW);
     isl_union_map_free(WAR);
     RAW = WAW = WAR = nullptr;
-    isl_ctx_reset_error(S.getIslCtx());
+    isl_ctx_reset_error(IslCtx.get());
   }
-  isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_ABORT);
-  isl_ctx_reset_operations(S.getIslCtx());
-  isl_ctx_set_max_operations(S.getIslCtx(), MaxOpsOld);
+  isl_options_set_on_error(IslCtx.get(), ISL_ON_ERROR_ABORT);
+  isl_ctx_reset_operations(IslCtx.get());
+  isl_ctx_set_max_operations(IslCtx.get(), MaxOpsOld);
 
   isl_union_map *STMT_RAW, *STMT_WAW, *STMT_WAR;
   STMT_RAW = isl_union_map_intersect_domain(
@@ -689,8 +689,8 @@ void Dependences::setReductionDependence
 }
 
 void DependenceInfo::recomputeDependences() {
-  releaseMemory();
-  D.calculateDependences(*S);
+  D.reset(new Dependences(S->getSharedIslCtx()));
+  D->calculateDependences(*S);
 }
 
 bool DependenceInfo::runOnScop(Scop &ScopVar) {

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=261100&r1=261099&r2=261100&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Wed Feb 17 09:49:21 2016
@@ -1788,7 +1788,8 @@ void Scop::addUserContext() {
   if (UserContextStr.empty())
     return;
 
-  isl_set *UserContext = isl_set_read_from_str(IslCtx, UserContextStr.c_str());
+  isl_set *UserContext =
+      isl_set_read_from_str(getIslCtx(), UserContextStr.c_str());
   isl_space *Space = getParamSpace();
   if (isl_space_dim(Space, isl_dim_param) !=
       isl_set_dim(UserContext, isl_dim_param)) {
@@ -1852,7 +1853,7 @@ void Scop::buildInvariantEquivalenceClas
 }
 
 void Scop::buildContext() {
-  isl_space *Space = isl_space_params_alloc(IslCtx, 0);
+  isl_space *Space = isl_space_params_alloc(getIslCtx(), 0);
   Context = isl_set_universe(isl_space_copy(Space));
   AssumedContext = isl_set_universe(Space);
 }
@@ -1869,7 +1870,7 @@ void Scop::addParameterBounds() {
 
 void Scop::realignParams() {
   // Add all parameters into a common model.
-  isl_space *Space = isl_space_params_alloc(IslCtx, ParameterIds.size());
+  isl_space *Space = isl_space_params_alloc(getIslCtx(), ParameterIds.size());
 
   for (const auto &ParamID : ParameterIds) {
     const SCEV *Parameter = ParamID.first;
@@ -2735,13 +2736,13 @@ static unsigned getMaxLoopDepthInRegion(
   return MaxLD - MinLD + 1;
 }
 
-Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, isl_ctx *Context,
-           unsigned MaxLoopDepth)
+Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, unsigned MaxLoopDepth)
     : SE(&ScalarEvolution), R(R), IsOptimized(false),
       HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false),
-      MaxLoopDepth(MaxLoopDepth), IslCtx(Context), Context(nullptr),
-      Affinator(this), AssumedContext(nullptr), BoundaryContext(nullptr),
-      Schedule(nullptr) {
+      MaxLoopDepth(MaxLoopDepth), IslCtx(isl_ctx_alloc(), isl_ctx_free),
+      Context(nullptr), Affinator(this), AssumedContext(nullptr),
+      BoundaryContext(nullptr), Schedule(nullptr) {
+  isl_options_set_on_error(getIslCtx(), ISL_ON_ERROR_ABORT);
   buildContext();
 }
 
@@ -2802,6 +2803,12 @@ Scop::~Scop() {
 
   for (const auto &IAClass : InvariantEquivClasses)
     isl_set_free(std::get<2>(IAClass));
+
+  // Explicitly release all Scop objects and the underlying isl objects before
+  // we relase the isl context.
+  Stmts.clear();
+  ScopArrayInfoMap.clear();
+  AccFuncMap.clear();
 }
 
 void Scop::updateAccessDimensionality() {
@@ -3311,7 +3318,7 @@ void Scop::print(raw_ostream &OS) const
 
 void Scop::dump() const { print(dbgs()); }
 
-isl_ctx *Scop::getIslCtx() const { return IslCtx; }
+isl_ctx *Scop::getIslCtx() const { return IslCtx.get(); }
 
 __isl_give isl_pw_aff *Scop::getPwAff(const SCEV *E, BasicBlock *BB) {
   return Affinator.getPwAff(E, BB);
@@ -4137,7 +4144,7 @@ void ScopInfo::addPHIReadAccess(PHINode
 
 void ScopInfo::buildScop(Region &R, AssumptionCache &AC) {
   unsigned MaxLoopDepth = getMaxLoopDepthInRegion(R, *LI, *SD);
-  scop.reset(new Scop(R, *SE, ctx, MaxLoopDepth));
+  scop.reset(new Scop(R, *SE, MaxLoopDepth));
 
   buildStmts(R, R);
   buildAccessFunctions(R, R, *SD->getInsnToMemAccMap(&R));
@@ -4168,15 +4175,9 @@ void ScopInfo::print(raw_ostream &OS, co
 void ScopInfo::clear() { scop.reset(); }
 
 //===----------------------------------------------------------------------===//
-ScopInfo::ScopInfo() : RegionPass(ID) {
-  ctx = isl_ctx_alloc();
-  isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
-}
+ScopInfo::ScopInfo() : RegionPass(ID) {}
 
-ScopInfo::~ScopInfo() {
-  clear();
-  isl_ctx_free(ctx);
-}
+ScopInfo::~ScopInfo() { clear(); }
 
 void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
   AU.addRequired<LoopInfoWrapperPass>();

Modified: polly/trunk/lib/CodeGen/IslAst.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslAst.cpp?rev=261100&r1=261099&r2=261100&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslAst.cpp (original)
+++ polly/trunk/lib/CodeGen/IslAst.cpp Wed Feb 17 09:49:21 2016
@@ -89,6 +89,7 @@ private:
   Scop *S;
   isl_ast_node *Root;
   isl_ast_expr *RunCondition;
+  std::shared_ptr<isl_ctx> Ctx;
 
   IslAst(Scop *Scop);
   void init(const Dependences &D);
@@ -377,7 +378,9 @@ static bool benefitsFromPolly(Scop *Scop
   return true;
 }
 
-IslAst::IslAst(Scop *Scop) : S(Scop), Root(nullptr), RunCondition(nullptr) {}
+IslAst::IslAst(Scop *Scop)
+    : S(Scop), Root(nullptr), RunCondition(nullptr),
+      Ctx(Scop->getSharedIslCtx()) {}
 
 void IslAst::init(const Dependences &D) {
   bool PerformParallelTest = PollyParallel || DetectParallel ||




More information about the llvm-commits mailing list