Index: polly/trunk/include/polly/DependenceInfo.h =================================================================== --- polly/trunk/include/polly/DependenceInfo.h +++ polly/trunk/include/polly/DependenceInfo.h @@ -137,15 +137,15 @@ /// 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 &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 @@ /// @brief Mapping from memory accesses to their reduction dependences. ReductionDependencesMapTy ReductionDependences; + + /// Isl context from the SCoP. + std::shared_ptr IslCtx; }; class DependenceInfo : public ScopPass { @@ -183,7 +186,7 @@ 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 @@ 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 @@ Scop *S; /// @brief Dependences struct for the current SCoP. - Dependences D; + std::auto_ptr D; }; } // End polly namespace. Index: polly/trunk/include/polly/ScopInfo.h =================================================================== --- polly/trunk/include/polly/ScopInfo.h +++ polly/trunk/include/polly/ScopInfo.h @@ -1273,7 +1273,13 @@ 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 IslCtx; /// @brief A map from basic blocks to SCoP statements. DenseMap StmtMap; @@ -1376,7 +1382,7 @@ 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 @@ /// @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 &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 @@ // The Scop std::unique_ptr scop; - isl_ctx *ctx; // Clear the context. void clear(); Index: polly/trunk/lib/Analysis/DependenceInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/DependenceInfo.cpp +++ polly/trunk/lib/Analysis/DependenceInfo.cpp @@ -283,10 +283,10 @@ 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 @@ 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 DependenceInfo::recomputeDependences() { - releaseMemory(); - D.calculateDependences(*S); + D.reset(new Dependences(S->getSharedIslCtx())); + D->calculateDependences(*S); } bool DependenceInfo::runOnScop(Scop &ScopVar) { Index: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/lib/Analysis/ScopInfo.cpp @@ -1788,7 +1788,8 @@ 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::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::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 @@ 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 @@ 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::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::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::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(); Index: polly/trunk/lib/CodeGen/IslAst.cpp =================================================================== --- polly/trunk/lib/CodeGen/IslAst.cpp +++ polly/trunk/lib/CodeGen/IslAst.cpp @@ -89,6 +89,7 @@ Scop *S; isl_ast_node *Root; isl_ast_expr *RunCondition; + std::shared_ptr Ctx; IslAst(Scop *Scop); void init(const Dependences &D); @@ -377,7 +378,9 @@ 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 ||