[polly] r303622 - [Polly][NewPM] Port IslAst to the new ScopPassManager

Philip Pfaffe via llvm-commits llvm-commits at lists.llvm.org
Tue May 23 03:12:56 PDT 2017


Author: pfaffe
Date: Tue May 23 05:12:56 2017
New Revision: 303622

URL: http://llvm.org/viewvc/llvm-project?rev=303622&view=rev
Log:
[Polly][NewPM] Port IslAst to the new ScopPassManager

Summary: This patch ports IslAst to the new PM. The change is mostly straightforward. The only major modification required is making IslAst move-only, to correctly manage the isl resources it owns.

Reviewers: grosser, Meinersbur

Reviewed By: grosser

Subscribers: nemanjai, pollydev, llvm-commits

Tags: #polly

Differential Revision: https://reviews.llvm.org/D33422

Modified:
    polly/trunk/include/polly/CodeGen/IslAst.h
    polly/trunk/include/polly/LinkAllPasses.h
    polly/trunk/lib/CodeGen/CodeGeneration.cpp
    polly/trunk/lib/CodeGen/IslAst.cpp
    polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp
    polly/trunk/lib/Support/RegisterPasses.cpp

Modified: polly/trunk/include/polly/CodeGen/IslAst.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/IslAst.h?rev=303622&r1=303621&r2=303622&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/IslAst.h (original)
+++ polly/trunk/include/polly/CodeGen/IslAst.h Tue May 23 05:12:56 2017
@@ -45,7 +45,7 @@ struct Dependences;
 
 class IslAst {
 public:
-  static IslAst *create(Scop *Scop, const Dependences &D);
+  static IslAst create(Scop &Scop, const Dependences &D);
   ~IslAst();
 
   /// Print a source code representation of the program.
@@ -62,20 +62,25 @@ public:
   /// @param Build The isl_build object to use to build the condition.
   ///
   /// @returns An ast expression that describes the necessary run-time check.
-  static isl_ast_expr *buildRunCondition(Scop *S,
+  static isl_ast_expr *buildRunCondition(Scop &S,
                                          __isl_keep isl_ast_build *Build);
 
+  IslAst(const IslAst &) = delete;
+  IslAst &operator=(const IslAst &) = delete;
+  IslAst(IslAst &&);
+  IslAst &operator=(IslAst &&) = delete;
+
 private:
-  Scop *S;
+  Scop &S;
   isl_ast_node *Root;
   isl_ast_expr *RunCondition;
   std::shared_ptr<isl_ctx> Ctx;
 
-  IslAst(Scop *Scop);
+  IslAst(Scop &Scop);
   void init(const Dependences &D);
 };
 
-class IslAstInfo : public ScopPass {
+class IslAstInfo {
 public:
   using MemoryAccessSet = SmallPtrSet<MemoryAccess *, 4>;
 
@@ -113,27 +118,14 @@ public:
   };
 
 private:
-  Scop *S;
-  IslAst *Ast;
+  Scop &S;
+  IslAst Ast;
 
 public:
-  static char ID;
-  IslAstInfo() : ScopPass(ID), S(nullptr), Ast(nullptr) {}
-
-  /// Build the AST for the given SCoP @p S.
-  bool runOnScop(Scop &S) override;
-
-  /// Register all analyses and transformation required.
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
-
-  /// Release the internal memory.
-  void releaseMemory() override;
-
-  /// Print a source code representation of the program.
-  void printScop(llvm::raw_ostream &OS, Scop &S) const override;
+  IslAstInfo(Scop &S, const Dependences &D) : S(S), Ast(IslAst::create(S, D)) {}
 
   /// Return a copy of the AST root node.
-  __isl_give isl_ast_node *getAst() const;
+  __isl_give isl_ast_node *getAst();
 
   /// Get the run condition.
   ///
@@ -141,12 +133,13 @@ public:
   /// assumptions that have been taken hold. If the run condition evaluates to
   /// zero/false some assumptions do not hold and the original code needs to
   /// be executed.
-  __isl_give isl_ast_expr *getRunCondition() const;
+  __isl_give isl_ast_expr *getRunCondition();
+
+  void print(raw_ostream &O);
 
   /// @name Extract information attached to an isl ast (for) node.
   ///
   ///{
-
   /// Get the complete payload attached to @p Node.
   static IslAstUserPayload *getNodePayload(__isl_keep isl_ast_node *Node);
 
@@ -183,10 +176,47 @@ public:
 
   ///}
 };
+
+struct IslAstAnalysis : public AnalysisInfoMixin<IslAstAnalysis> {
+  static AnalysisKey Key;
+  using Result = IslAstInfo;
+  IslAstInfo run(Scop &S, ScopAnalysisManager &SAM,
+                 ScopStandardAnalysisResults &SAR);
+};
+
+class IslAstInfoWrapperPass : public ScopPass {
+  std::unique_ptr<IslAstInfo> Ast;
+
+public:
+  static char ID;
+  IslAstInfoWrapperPass() : ScopPass(ID) {}
+
+  IslAstInfo &getAI() { return *Ast; }
+  const IslAstInfo &getAI() const { return *Ast; }
+
+  /// Build the AST for the given SCoP @p S.
+  bool runOnScop(Scop &S) override;
+
+  /// Register all analyses and transformation required.
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+  /// Release the internal memory.
+  void releaseMemory() override;
+
+  /// Print a source code representation of the program.
+  void printScop(llvm::raw_ostream &OS, Scop &S) const override;
+};
+
+struct IslAstPrinterPass : public PassInfoMixin<IslAstPrinterPass> {
+  IslAstPrinterPass(raw_ostream &O) : Stream(O) {}
+  PreservedAnalyses run(Scop &S, ScopAnalysisManager &SAM,
+                        ScopStandardAnalysisResults &, SPMUpdater &U);
+  raw_ostream &Stream;
+};
 } // namespace polly
 
 namespace llvm {
 class PassRegistry;
-void initializeIslAstInfoPass(llvm::PassRegistry &);
+void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &);
 } // namespace llvm
 #endif /* POLLY_ISL_AST_H */

Modified: polly/trunk/include/polly/LinkAllPasses.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/LinkAllPasses.h?rev=303622&r1=303621&r2=303622&view=diff
==============================================================================
--- polly/trunk/include/polly/LinkAllPasses.h (original)
+++ polly/trunk/include/polly/LinkAllPasses.h Tue May 23 05:12:56 2017
@@ -46,7 +46,7 @@ llvm::Pass *createPolyhedralInfoPass();
 llvm::Pass *createScopDetectionWrapperPassPass();
 llvm::Pass *createScopInfoRegionPassPass();
 llvm::Pass *createScopInfoWrapperPassPass();
-llvm::Pass *createIslAstInfoPass();
+llvm::Pass *createIslAstInfoWrapperPassPass();
 llvm::Pass *createCodeGenerationPass();
 #ifdef GPU_CODEGEN
 llvm::Pass *createPPCGCodeGenerationPass(GPUArch Arch = GPUArch::NVPTX64,
@@ -82,7 +82,7 @@ struct PollyForcePassLinking {
     polly::createScopInfoRegionPassPass();
     polly::createPollyCanonicalizePass();
     polly::createPolyhedralInfoPass();
-    polly::createIslAstInfoPass();
+    polly::createIslAstInfoWrapperPassPass();
     polly::createCodeGenerationPass();
 #ifdef GPU_CODEGEN
     polly::createPPCGCodeGenerationPass();
@@ -103,7 +103,7 @@ void initializeCodePreparationPass(llvm:
 void initializeDeadCodeElimPass(llvm::PassRegistry &);
 void initializeJSONExporterPass(llvm::PassRegistry &);
 void initializeJSONImporterPass(llvm::PassRegistry &);
-void initializeIslAstInfoPass(llvm::PassRegistry &);
+void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &);
 void initializeCodeGenerationPass(llvm::PassRegistry &);
 #ifdef GPU_CODEGEN
 void initializePPCGCodeGenerationPass(llvm::PassRegistry &);

Modified: polly/trunk/lib/CodeGen/CodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/CodeGeneration.cpp?rev=303622&r1=303621&r2=303622&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/CodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/CodeGeneration.cpp Tue May 23 05:12:56 2017
@@ -80,7 +80,7 @@ public:
                 "SCoP ==\n";
       S.print(errs());
       errs() << "\n== The isl AST ==\n";
-      AI->printScop(errs(), S);
+      AI->print(errs());
       errs() << "\n== The invalid function ==\n";
       F.print(errs());
     });
@@ -167,7 +167,7 @@ public:
 
   /// Generate LLVM-IR for the SCoP @p S.
   bool runOnScop(Scop &S) override {
-    AI = &getAnalysis<IslAstInfo>();
+    AI = &getAnalysis<IslAstInfoWrapperPass>().getAI();
 
     // Check if we created an isl_ast root node, otherwise exit.
     isl_ast_node *AstRoot = AI->getAst();
@@ -273,7 +273,7 @@ public:
   /// Register all analyses and transformation required.
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<DominatorTreeWrapperPass>();
-    AU.addRequired<IslAstInfo>();
+    AU.addRequired<IslAstInfoWrapperPass>();
     AU.addRequired<RegionInfoPass>();
     AU.addRequired<ScalarEvolutionWrapperPass>();
     AU.addRequired<ScopDetectionWrapperPass>();
@@ -287,7 +287,7 @@ public:
     AU.addPreserved<LoopInfoWrapperPass>();
     AU.addPreserved<DominatorTreeWrapperPass>();
     AU.addPreserved<GlobalsAAWrapperPass>();
-    AU.addPreserved<IslAstInfo>();
+    AU.addPreserved<IslAstInfoWrapperPass>();
     AU.addPreserved<ScopDetectionWrapperPass>();
     AU.addPreserved<ScalarEvolutionWrapperPass>();
     AU.addPreserved<SCEVAAWrapperPass>();

Modified: polly/trunk/lib/CodeGen/IslAst.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslAst.cpp?rev=303622&r1=303621&r2=303622&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslAst.cpp (original)
+++ polly/trunk/lib/CodeGen/IslAst.cpp Tue May 23 05:12:56 2017
@@ -332,18 +332,18 @@ buildCondition(__isl_keep isl_ast_build
 }
 
 __isl_give isl_ast_expr *
-IslAst::buildRunCondition(Scop *S, __isl_keep isl_ast_build *Build) {
+IslAst::buildRunCondition(Scop &S, __isl_keep isl_ast_build *Build) {
   isl_ast_expr *RunCondition;
 
   // The conditions that need to be checked at run-time for this scop are
   // available as an isl_set in the runtime check context from which we can
   // directly derive a run-time condition.
-  auto *PosCond = isl_ast_build_expr_from_set(Build, S->getAssumedContext());
-  if (S->hasTrivialInvalidContext()) {
+  auto *PosCond = isl_ast_build_expr_from_set(Build, S.getAssumedContext());
+  if (S.hasTrivialInvalidContext()) {
     RunCondition = PosCond;
   } else {
     auto *ZeroV = isl_val_zero(isl_ast_build_get_ctx(Build));
-    auto *NegCond = isl_ast_build_expr_from_set(Build, S->getInvalidContext());
+    auto *NegCond = isl_ast_build_expr_from_set(Build, S.getInvalidContext());
     auto *NotNegCond = isl_ast_expr_eq(isl_ast_expr_from_val(ZeroV), NegCond);
     RunCondition = isl_ast_expr_and(PosCond, NotNegCond);
   }
@@ -352,7 +352,7 @@ IslAst::buildRunCondition(Scop *S, __isl
   // group which consists of read only and non read only (read write) accesses.
   // This operation is by construction quadratic in the read-write pointers and
   // linear in the read only pointers in each alias group.
-  for (const Scop::MinMaxVectorPairTy &MinMaxAccessPair : S->getAliasGroups()) {
+  for (const Scop::MinMaxVectorPairTy &MinMaxAccessPair : S.getAliasGroups()) {
     auto &MinMaxReadWrite = MinMaxAccessPair.first;
     auto &MinMaxReadOnly = MinMaxAccessPair.second;
     auto RWAccEnd = MinMaxReadWrite.end();
@@ -378,23 +378,23 @@ IslAst::buildRunCondition(Scop *S, __isl
 ///       In order to improve the cost model we could either keep track of
 ///       performed optimizations (e.g., tiling) or compute properties on the
 ///       original as well as optimized SCoP (e.g., #stride-one-accesses).
-static bool benefitsFromPolly(Scop *Scop, bool PerformParallelTest) {
+static bool benefitsFromPolly(Scop &Scop, bool PerformParallelTest) {
 
   if (PollyProcessUnprofitable)
     return true;
 
   // Check if nothing interesting happened.
-  if (!PerformParallelTest && !Scop->isOptimized() &&
-      Scop->getAliasGroups().empty())
+  if (!PerformParallelTest && !Scop.isOptimized() &&
+      Scop.getAliasGroups().empty())
     return false;
 
   // The default assumption is that Polly improves the code.
   return true;
 }
 
-IslAst::IslAst(Scop *Scop)
+IslAst::IslAst(Scop &Scop)
     : S(Scop), Root(nullptr), RunCondition(nullptr),
-      Ctx(Scop->getSharedIslCtx()) {}
+      Ctx(Scop.getSharedIslCtx()) {}
 
 void IslAst::init(const Dependences &D) {
   bool PerformParallelTest = PollyParallel || DetectParallel ||
@@ -403,25 +403,25 @@ void IslAst::init(const Dependences &D)
   // We can not perform the dependence analysis and, consequently,
   // the parallel code generation in case the schedule tree contains
   // extension nodes.
-  auto *ScheduleTree = S->getScheduleTree();
+  auto *ScheduleTree = S.getScheduleTree();
   PerformParallelTest =
-      PerformParallelTest && !S->containsExtensionNode(ScheduleTree);
+      PerformParallelTest && !S.containsExtensionNode(ScheduleTree);
   isl_schedule_free(ScheduleTree);
 
   // Skip AST and code generation if there was no benefit achieved.
   if (!benefitsFromPolly(S, PerformParallelTest))
     return;
 
-  isl_ctx *Ctx = S->getIslCtx();
+  isl_ctx *Ctx = S.getIslCtx();
   isl_options_set_ast_build_atomic_upper_bound(Ctx, true);
   isl_options_set_ast_build_detect_min_max(Ctx, true);
   isl_ast_build *Build;
   AstBuildUserInfo BuildInfo;
 
   if (UseContext)
-    Build = isl_ast_build_from_context(S->getContext());
+    Build = isl_ast_build_from_context(S.getContext());
   else
-    Build = isl_ast_build_from_context(isl_set_universe(S->getParamSpace()));
+    Build = isl_ast_build_from_context(isl_set_universe(S.getParamSpace()));
 
   Build = isl_ast_build_set_at_each_domain(Build, AtEachDomain, nullptr);
 
@@ -443,17 +443,23 @@ void IslAst::init(const Dependences &D)
 
   RunCondition = buildRunCondition(S, Build);
 
-  Root = isl_ast_build_node_from_schedule(Build, S->getScheduleTree());
+  Root = isl_ast_build_node_from_schedule(Build, S.getScheduleTree());
 
   isl_ast_build_free(Build);
 }
 
-IslAst *IslAst::create(Scop *Scop, const Dependences &D) {
-  auto Ast = new IslAst(Scop);
-  Ast->init(D);
+IslAst IslAst::create(Scop &Scop, const Dependences &D) {
+  IslAst Ast{Scop};
+  Ast.init(D);
   return Ast;
 }
 
+IslAst::IslAst(IslAst &&O)
+    : S(O.S), Root(O.Root), RunCondition(O.RunCondition), Ctx(O.Ctx) {
+  O.Root = nullptr;
+  O.RunCondition = nullptr;
+}
+
 IslAst::~IslAst() {
   isl_ast_node_free(Root);
   isl_ast_expr_free(RunCondition);
@@ -464,31 +470,9 @@ __isl_give isl_ast_expr *IslAst::getRunC
   return isl_ast_expr_copy(RunCondition);
 }
 
-void IslAstInfo::releaseMemory() {
-  if (Ast) {
-    delete Ast;
-    Ast = nullptr;
-  }
-}
-
-bool IslAstInfo::runOnScop(Scop &Scop) {
-  if (Ast)
-    delete Ast;
-
-  S = &Scop;
-
-  const Dependences &D =
-      getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
-
-  Ast = IslAst::create(&Scop, D);
-
-  DEBUG(printScop(dbgs(), Scop));
-  return false;
-}
-
-__isl_give isl_ast_node *IslAstInfo::getAst() const { return Ast->getAst(); }
-__isl_give isl_ast_expr *IslAstInfo::getRunCondition() const {
-  return Ast->getRunCondition();
+__isl_give isl_ast_node *IslAstInfo::getAst() { return Ast.getAst(); }
+__isl_give isl_ast_expr *IslAstInfo::getRunCondition() {
+  return Ast.getRunCondition();
 }
 
 IslAstUserPayload *IslAstInfo::getNodePayload(__isl_keep isl_ast_node *Node) {
@@ -569,9 +553,15 @@ isl_ast_build *IslAstInfo::getBuild(__is
   return Payload ? Payload->Build : nullptr;
 }
 
-void IslAstInfo::printScop(raw_ostream &OS, Scop &S) const {
+IslAstInfo IslAstAnalysis::run(Scop &S, ScopAnalysisManager &SAM,
+                               ScopStandardAnalysisResults &SAR) {
+  return {S, SAM.getResult<DependenceAnalysis>(S, SAR).getDependences(
+                 Dependences::AL_Statement)};
+}
+
+void IslAstInfo::print(raw_ostream &OS) {
   isl_ast_print_options *Options;
-  isl_ast_node *RootNode = getAst();
+  isl_ast_node *RootNode = Ast.getAst();
   Function &F = S.getFunction();
 
   OS << ":: isl ast :: " << F.getName() << " :: " << S.getNameStr() << "\n";
@@ -586,7 +576,7 @@ void IslAstInfo::printScop(raw_ostream &
     return;
   }
 
-  isl_ast_expr *RunCondition = getRunCondition();
+  isl_ast_expr *RunCondition = Ast.getRunCondition();
   char *RtCStr, *AstStr;
 
   Options = isl_ast_print_options_alloc(S.getIslCtx());
@@ -621,21 +611,49 @@ void IslAstInfo::printScop(raw_ostream &
   isl_printer_free(P);
 }
 
-void IslAstInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+AnalysisKey IslAstAnalysis::Key;
+PreservedAnalyses IslAstPrinterPass::run(Scop &S, ScopAnalysisManager &SAM,
+                                         ScopStandardAnalysisResults &SAR,
+                                         SPMUpdater &U) {
+
+  auto &Ast = SAM.getResult<IslAstAnalysis>(S, SAR);
+  Ast.print(Stream);
+  return PreservedAnalyses::all();
+}
+
+void IslAstInfoWrapperPass::releaseMemory() { Ast.reset(); }
+
+bool IslAstInfoWrapperPass::runOnScop(Scop &Scop) {
+  const Dependences &D =
+      getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
+
+  Ast.reset(new IslAstInfo(Scop, D));
+
+  DEBUG(printScop(dbgs(), Scop));
+  return false;
+}
+void IslAstInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
   // Get the Common analysis usage of ScopPasses.
   ScopPass::getAnalysisUsage(AU);
   AU.addRequired<ScopInfoRegionPass>();
   AU.addRequired<DependenceInfo>();
 }
 
-char IslAstInfo::ID = 0;
+void IslAstInfoWrapperPass::printScop(raw_ostream &OS, Scop &S) const {
+  if (Ast)
+    Ast->print(OS);
+}
 
-Pass *polly::createIslAstInfoPass() { return new IslAstInfo(); }
+char IslAstInfoWrapperPass::ID = 0;
+
+Pass *polly::createIslAstInfoWrapperPassPass() {
+  return new IslAstInfoWrapperPass();
+}
 
-INITIALIZE_PASS_BEGIN(IslAstInfo, "polly-ast",
+INITIALIZE_PASS_BEGIN(IslAstInfoWrapperPass, "polly-ast",
                       "Polly - Generate an AST of the SCoP (isl)", false,
                       false);
 INITIALIZE_PASS_DEPENDENCY(ScopInfoRegionPass);
 INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
-INITIALIZE_PASS_END(IslAstInfo, "polly-ast",
+INITIALIZE_PASS_END(IslAstInfoWrapperPass, "polly-ast",
                     "Polly - Generate an AST from the SCoP (isl)", false, false)

Modified: polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp?rev=303622&r1=303621&r2=303622&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp Tue May 23 05:12:56 2017
@@ -2645,7 +2645,7 @@ public:
     NodeBuilder.addParameters(S->getContext());
 
     isl_ast_build *Build = isl_ast_build_alloc(S->getIslCtx());
-    isl_ast_expr *Condition = IslAst::buildRunCondition(S, Build);
+    isl_ast_expr *Condition = IslAst::buildRunCondition(*S, Build);
     isl_ast_expr *SufficientCompute = createSufficientComputeCheck(*S, Build);
     Condition = isl_ast_expr_and(Condition, SufficientCompute);
     isl_ast_build_free(Build);

Modified: polly/trunk/lib/Support/RegisterPasses.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/RegisterPasses.cpp?rev=303622&r1=303621&r2=303622&view=diff
==============================================================================
--- polly/trunk/lib/Support/RegisterPasses.cpp (original)
+++ polly/trunk/lib/Support/RegisterPasses.cpp Tue May 23 05:12:56 2017
@@ -230,7 +230,7 @@ void initializePollyPasses(PassRegistry
   initializeDependenceInfoWrapperPassPass(Registry);
   initializeJSONExporterPass(Registry);
   initializeJSONImporterPass(Registry);
-  initializeIslAstInfoPass(Registry);
+  initializeIslAstInfoWrapperPassPass(Registry);
   initializeIslScheduleOptimizerPass(Registry);
   initializePollyCanonicalizePass(Registry);
   initializePolyhedralInfoPass(Registry);
@@ -333,7 +333,7 @@ void registerPollyPasses(llvm::legacy::P
   } else {
     switch (CodeGeneration) {
     case CODEGEN_AST:
-      PM.add(polly::createIslAstInfoPass());
+      PM.add(polly::createIslAstInfoWrapperPassPass());
       break;
     case CODEGEN_FULL:
       PM.add(polly::createCodeGenerationPass());




More information about the llvm-commits mailing list