[llvm] 6b3b873 - [polly] migrate -polly-show to the new pass manager

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 12:06:09 PDT 2022


Author: Michael Kruse
Date: 2022-05-09T14:04:29-05:00
New Revision: 6b3b87376bfe86306c5032fc68ae53d6a524520e

URL: https://github.com/llvm/llvm-project/commit/6b3b87376bfe86306c5032fc68ae53d6a524520e
DIFF: https://github.com/llvm/llvm-project/commit/6b3b87376bfe86306c5032fc68ae53d6a524520e.diff

LOG: [polly] migrate -polly-show to the new pass manager

Reviewed By: Meinersbur

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

Added: 
    polly/include/polly/ScopGraphPrinter.h
    polly/test/ScopDetect/dot-scops-npm.ll

Modified: 
    llvm/include/llvm/Analysis/RegionPrinter.h
    llvm/lib/Analysis/RegionPrinter.cpp
    polly/include/polly/LinkAllPasses.h
    polly/lib/Analysis/ScopGraphPrinter.cpp
    polly/lib/Support/PollyPasses.def
    polly/lib/Support/RegisterPasses.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/RegionPrinter.h b/llvm/include/llvm/Analysis/RegionPrinter.h
index 154ac35c486ad..501a5406236e9 100644
--- a/llvm/include/llvm/Analysis/RegionPrinter.h
+++ b/llvm/include/llvm/Analysis/RegionPrinter.h
@@ -14,6 +14,9 @@
 #ifndef LLVM_ANALYSIS_REGIONPRINTER_H
 #define LLVM_ANALYSIS_REGIONPRINTER_H
 
+#include "llvm/Analysis/DOTGraphTraitsPass.h"
+#include "llvm/Analysis/RegionInfo.h"
+
 namespace llvm {
   class FunctionPass;
   class Function;
@@ -24,6 +27,13 @@ namespace llvm {
   FunctionPass *createRegionPrinterPass();
   FunctionPass *createRegionOnlyPrinterPass();
 
+  template <>
+  struct DOTGraphTraits<RegionNode *> : public DefaultDOTGraphTraits {
+    DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
+
+    std::string getNodeLabel(RegionNode *Node, RegionNode *Graph);
+  };
+
 #ifndef NDEBUG
   /// Open a viewer to display the GraphViz vizualization of the analysis
   /// result.

diff  --git a/llvm/lib/Analysis/RegionPrinter.cpp b/llvm/lib/Analysis/RegionPrinter.cpp
index c454b9760a768..fbd3d17febff4 100644
--- a/llvm/lib/Analysis/RegionPrinter.cpp
+++ b/llvm/lib/Analysis/RegionPrinter.cpp
@@ -31,28 +31,20 @@ onlySimpleRegions("only-simple-regions",
                   cl::init(false));
 
 namespace llvm {
-template<>
-struct DOTGraphTraits<RegionNode*> : public DefaultDOTGraphTraits {
 
-  DOTGraphTraits (bool isSimple=false)
-    : DefaultDOTGraphTraits(isSimple) {}
+std::string DOTGraphTraits<RegionNode *>::getNodeLabel(RegionNode *Node,
+                                                       RegionNode *Graph) {
+  if (!Node->isSubRegion()) {
+    BasicBlock *BB = Node->getNodeAs<BasicBlock>();
 
-  std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
-
-    if (!Node->isSubRegion()) {
-      BasicBlock *BB = Node->getNodeAs<BasicBlock>();
-
-      if (isSimple())
-        return DOTGraphTraits<DOTFuncInfo *>
-          ::getSimpleNodeLabel(BB, nullptr);
-      else
-        return DOTGraphTraits<DOTFuncInfo *>
-          ::getCompleteNodeLabel(BB, nullptr);
-    }
-
-    return "Not implemented";
+    if (isSimple())
+      return DOTGraphTraits<DOTFuncInfo *>::getSimpleNodeLabel(BB, nullptr);
+    else
+      return DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel(BB, nullptr);
   }
-};
+
+  return "Not implemented";
+}
 
 template <>
 struct DOTGraphTraits<RegionInfo *> : public DOTGraphTraits<RegionNode *> {
@@ -134,7 +126,7 @@ struct DOTGraphTraits<RegionInfo *> : public DOTGraphTraits<RegionNode *> {
     printRegionCluster(*G->getTopLevelRegion(), GW, 4);
   }
 };
-} //end namespace llvm
+} // end namespace llvm
 
 namespace {
 

diff  --git a/polly/include/polly/LinkAllPasses.h b/polly/include/polly/LinkAllPasses.h
index 88384e86ba65c..3fced85f527ba 100644
--- a/polly/include/polly/LinkAllPasses.h
+++ b/polly/include/polly/LinkAllPasses.h
@@ -35,10 +35,10 @@ llvm::Pass *createDependenceInfoPrinterLegacyPass(llvm::raw_ostream &OS);
 llvm::Pass *createDependenceInfoWrapperPassPass();
 llvm::Pass *
 createDependenceInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS);
-llvm::Pass *createDOTOnlyPrinterPass();
-llvm::Pass *createDOTOnlyViewerPass();
-llvm::Pass *createDOTPrinterPass();
-llvm::Pass *createDOTViewerPass();
+llvm::Pass *createDOTOnlyPrinterWrapperPass();
+llvm::Pass *createDOTOnlyViewerWrapperPass();
+llvm::Pass *createDOTPrinterWrapperPass();
+llvm::Pass *createDOTViewerWrapperPass();
 llvm::Pass *createJSONExporterPass();
 llvm::Pass *createJSONImporterPass();
 llvm::Pass *createJSONImporterPrinterLegacyPass(llvm::raw_ostream &OS);
@@ -94,10 +94,10 @@ struct PollyForcePassLinking {
     polly::createDependenceInfoPrinterLegacyPass(llvm::outs());
     polly::createDependenceInfoWrapperPassPass();
     polly::createDependenceInfoPrinterLegacyFunctionPass(llvm::outs());
-    polly::createDOTOnlyPrinterPass();
-    polly::createDOTOnlyViewerPass();
-    polly::createDOTPrinterPass();
-    polly::createDOTViewerPass();
+    polly::createDOTOnlyPrinterWrapperPass();
+    polly::createDOTOnlyViewerWrapperPass();
+    polly::createDOTPrinterWrapperPass();
+    polly::createDOTViewerWrapperPass();
     polly::createJSONExporterPass();
     polly::createJSONImporterPass();
     polly::createJSONImporterPrinterLegacyPass(llvm::outs());

diff  --git a/polly/include/polly/ScopGraphPrinter.h b/polly/include/polly/ScopGraphPrinter.h
new file mode 100644
index 0000000000000..2cf64b8eaee3b
--- /dev/null
+++ b/polly/include/polly/ScopGraphPrinter.h
@@ -0,0 +1,94 @@
+//===- GraphPrinter.h - Create a DOT output describing the Scop. ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Create a DOT output describing the Scop.
+//
+// For each function a dot file is created that shows the control flow graph of
+// the function and highlights the detected Scops.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCOP_GRAPH_PRINTER_H
+#define POLLY_SCOP_GRAPH_PRINTER_H
+
+#include "polly/ScopDetection.h"
+#include "polly/Support/ScopLocation.h"
+#include "llvm/Analysis/DOTGraphTraitsPass.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Analysis/RegionPrinter.h"
+#include "llvm/IR/PassManager.h"
+
+using namespace polly;
+using namespace llvm;
+
+namespace llvm {
+
+template <>
+struct GraphTraits<ScopDetection *> : public GraphTraits<RegionInfo *> {
+  static NodeRef getEntryNode(ScopDetection *SD) {
+    return GraphTraits<RegionInfo *>::getEntryNode(SD->getRI());
+  }
+  static nodes_iterator nodes_begin(ScopDetection *SD) {
+    return nodes_iterator::begin(getEntryNode(SD));
+  }
+  static nodes_iterator nodes_end(ScopDetection *SD) {
+    return nodes_iterator::end(getEntryNode(SD));
+  }
+};
+
+template <>
+struct DOTGraphTraits<ScopDetection *> : public DOTGraphTraits<RegionNode *> {
+  DOTGraphTraits(bool isSimple = false)
+      : DOTGraphTraits<RegionNode *>(isSimple) {}
+  static std::string getGraphName(ScopDetection *SD) { return "Scop Graph"; }
+
+  std::string getEdgeAttributes(RegionNode *srcNode,
+                                GraphTraits<RegionInfo *>::ChildIteratorType CI,
+                                ScopDetection *SD);
+
+  std::string getNodeLabel(RegionNode *Node, ScopDetection *SD) {
+    return DOTGraphTraits<RegionNode *>::getNodeLabel(
+        Node, reinterpret_cast<RegionNode *>(SD->getRI()->getTopLevelRegion()));
+  }
+
+  static std::string escapeString(llvm::StringRef String);
+
+  /// Print the cluster of the subregions. This groups the single basic blocks
+  /// and adds a 
diff erent background color for each group.
+  static void printRegionCluster(ScopDetection *SD, const Region *R,
+                                 raw_ostream &O, unsigned depth = 0);
+
+  static void addCustomGraphFeatures(ScopDetection *SD,
+                                     GraphWriter<ScopDetection *> &GW);
+};
+} // end namespace llvm
+
+namespace polly {
+
+struct ScopViewer : public DOTGraphTraitsViewer<ScopAnalysis, false> {
+  ScopViewer() : DOTGraphTraitsViewer<ScopAnalysis, false>("scops") {}
+
+  bool processFunction(Function &F, const ScopDetection &SD) override;
+};
+
+struct ScopOnlyViewer : public DOTGraphTraitsViewer<ScopAnalysis, false> {
+  ScopOnlyViewer() : DOTGraphTraitsViewer<ScopAnalysis, false>("scops-only") {}
+};
+
+struct ScopPrinter : public DOTGraphTraitsPrinter<ScopAnalysis, false> {
+  ScopPrinter() : DOTGraphTraitsPrinter<ScopAnalysis, false>("scops") {}
+};
+
+struct ScopOnlyPrinter : public DOTGraphTraitsPrinter<ScopAnalysis, true> {
+  ScopOnlyPrinter() : DOTGraphTraitsPrinter<ScopAnalysis, true>("scopsonly") {}
+};
+
+} // end namespace polly
+
+#endif /* POLLY_SCOP_GRAPH_PRINTER_H */

diff  --git a/polly/lib/Analysis/ScopGraphPrinter.cpp b/polly/lib/Analysis/ScopGraphPrinter.cpp
index 046f1ac620b89..fbbbe74c67f49 100644
--- a/polly/lib/Analysis/ScopGraphPrinter.cpp
+++ b/polly/lib/Analysis/ScopGraphPrinter.cpp
@@ -13,12 +13,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "polly/ScopGraphPrinter.h"
 #include "polly/LinkAllPasses.h"
 #include "polly/ScopDetection.h"
-#include "polly/Support/ScopLocation.h"
-#include "llvm/Analysis/DOTGraphTraitsPass.h"
-#include "llvm/Analysis/RegionInfo.h"
-#include "llvm/Analysis/RegionIterator.h"
 #include "llvm/Support/CommandLine.h"
 
 using namespace polly;
@@ -33,175 +30,125 @@ static cl::opt<bool> ViewAll("polly-view-all",
                              cl::Hidden, cl::init(false), cl::ZeroOrMore);
 
 namespace llvm {
-template <>
-struct GraphTraits<ScopDetection *> : public GraphTraits<RegionInfo *> {
-  static NodeRef getEntryNode(ScopDetection *SD) {
-    return GraphTraits<RegionInfo *>::getEntryNode(SD->getRI());
-  }
-  static nodes_iterator nodes_begin(ScopDetection *SD) {
-    return nodes_iterator::begin(getEntryNode(SD));
-  }
-  static nodes_iterator nodes_end(ScopDetection *SD) {
-    return nodes_iterator::end(getEntryNode(SD));
-  }
-};
-
-template <>
-struct GraphTraits<ScopDetectionWrapperPass *>
-    : public GraphTraits<ScopDetection *> {
-  static NodeRef getEntryNode(ScopDetectionWrapperPass *P) {
-    return GraphTraits<ScopDetection *>::getEntryNode(&P->getSD());
-  }
-  static nodes_iterator nodes_begin(ScopDetectionWrapperPass *P) {
-    return nodes_iterator::begin(getEntryNode(P));
-  }
-  static nodes_iterator nodes_end(ScopDetectionWrapperPass *P) {
-    return nodes_iterator::end(getEntryNode(P));
-  }
-};
-
-template <> struct DOTGraphTraits<RegionNode *> : public DefaultDOTGraphTraits {
-  DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
-
-  std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
-    if (!Node->isSubRegion()) {
-      BasicBlock *BB = Node->getNodeAs<BasicBlock>();
 
-      if (isSimple())
-        return DOTGraphTraits<DOTFuncInfo *>::getSimpleNodeLabel(BB, nullptr);
+std::string DOTGraphTraits<ScopDetection *>::getEdgeAttributes(
+    RegionNode *srcNode, GraphTraits<RegionInfo *>::ChildIteratorType CI,
+    ScopDetection *SD) {
+  RegionNode *destNode = *CI;
 
-      else
-        return DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel(BB, nullptr);
-    }
-
-    return "Not implemented";
-  }
-};
+  if (srcNode->isSubRegion() || destNode->isSubRegion())
+    return "";
 
-template <>
-struct DOTGraphTraits<ScopDetectionWrapperPass *>
-    : public DOTGraphTraits<RegionNode *> {
-  DOTGraphTraits(bool isSimple = false)
-      : DOTGraphTraits<RegionNode *>(isSimple) {}
-  static std::string getGraphName(ScopDetectionWrapperPass *SD) {
-    return "Scop Graph";
-  }
+  // In case of a backedge, do not use it to define the layout of the nodes.
+  BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
+  BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
 
-  std::string getEdgeAttributes(RegionNode *srcNode,
-                                GraphTraits<RegionInfo *>::ChildIteratorType CI,
-                                ScopDetectionWrapperPass *P) {
-    RegionNode *destNode = *CI;
-    auto *SD = &P->getSD();
+  RegionInfo *RI = SD->getRI();
+  Region *R = RI->getRegionFor(destBB);
 
-    if (srcNode->isSubRegion() || destNode->isSubRegion())
-      return "";
+  while (R && R->getParent())
+    if (R->getParent()->getEntry() == destBB)
+      R = R->getParent();
+    else
+      break;
 
-    // In case of a backedge, do not use it to define the layout of the nodes.
-    BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
-    BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
+  if (R && R->getEntry() == destBB && R->contains(srcBB))
+    return "constraint=false";
 
-    RegionInfo *RI = SD->getRI();
-    Region *R = RI->getRegionFor(destBB);
+  return "";
+}
 
-    while (R && R->getParent())
-      if (R->getParent()->getEntry() == destBB)
-        R = R->getParent();
-      else
-        break;
+std::string
+DOTGraphTraits<ScopDetection *>::escapeString(llvm::StringRef String) {
+  std::string Escaped;
 
-    if (R && R->getEntry() == destBB && R->contains(srcBB))
-      return "constraint=false";
+  for (const auto &C : String) {
+    if (C == '"')
+      Escaped += '\\';
 
-    return "";
+    Escaped += C;
   }
-
-  std::string getNodeLabel(RegionNode *Node, ScopDetectionWrapperPass *P) {
-    return DOTGraphTraits<RegionNode *>::getNodeLabel(
-        Node, reinterpret_cast<RegionNode *>(
-                  P->getSD().getRI()->getTopLevelRegion()));
+  return Escaped;
+}
+
+void DOTGraphTraits<ScopDetection *>::printRegionCluster(ScopDetection *SD,
+                                                         const Region *R,
+                                                         raw_ostream &O,
+                                                         unsigned depth) {
+  O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void *>(R)
+                      << " {\n";
+  unsigned LineBegin, LineEnd;
+  std::string FileName;
+
+  getDebugLocation(R, LineBegin, LineEnd, FileName);
+
+  std::string Location;
+  if (LineBegin != (unsigned)-1) {
+    Location = escapeString(FileName + ":" + std::to_string(LineBegin) + "-" +
+                            std::to_string(LineEnd) + "\n");
   }
 
-  static std::string escapeString(std::string String) {
-    std::string Escaped;
-
-    for (const auto &C : String) {
-      if (C == '"')
-        Escaped += '\\';
-
-      Escaped += C;
-    }
-    return Escaped;
-  }
+  std::string ErrorMessage = SD->regionIsInvalidBecause(R);
+  ErrorMessage = escapeString(ErrorMessage);
+  O.indent(2 * (depth + 1))
+      << "label = \"" << Location << ErrorMessage << "\";\n";
 
-  // Print the cluster of the subregions. This groups the single basic blocks
-  // and adds a 
diff erent background color for each group.
-  static void printRegionCluster(ScopDetection *SD, const Region *R,
-                                 raw_ostream &O, unsigned depth = 0) {
-    O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void *>(R)
-                        << " {\n";
-    unsigned LineBegin, LineEnd;
-    std::string FileName;
+  if (SD->isMaxRegionInScop(*R)) {
+    O.indent(2 * (depth + 1)) << "style = filled;\n";
 
-    getDebugLocation(R, LineBegin, LineEnd, FileName);
+    // Set color to green.
+    O.indent(2 * (depth + 1)) << "color = 3";
+  } else {
+    O.indent(2 * (depth + 1)) << "style = solid;\n";
 
-    std::string Location;
-    if (LineBegin != (unsigned)-1) {
-      Location = escapeString(FileName + ":" + std::to_string(LineBegin) + "-" +
-                              std::to_string(LineEnd) + "\n");
-    }
+    int color = (R->getDepth() * 2 % 12) + 1;
 
-    std::string ErrorMessage = SD->regionIsInvalidBecause(R);
-    ErrorMessage = escapeString(ErrorMessage);
-    O.indent(2 * (depth + 1))
-        << "label = \"" << Location << ErrorMessage << "\";\n";
+    // We do not want green again.
+    if (color == 3)
+      color = 6;
 
-    if (SD->isMaxRegionInScop(*R)) {
-      O.indent(2 * (depth + 1)) << "style = filled;\n";
-
-      // Set color to green.
-      O.indent(2 * (depth + 1)) << "color = 3";
-    } else {
-      O.indent(2 * (depth + 1)) << "style = solid;\n";
+    O.indent(2 * (depth + 1)) << "color = " << color << "\n";
+  }
 
-      int color = (R->getDepth() * 2 % 12) + 1;
+  for (const auto &SubRegion : *R)
+    printRegionCluster(SD, SubRegion.get(), O, depth + 1);
 
-      // We do not want green again.
-      if (color == 3)
-        color = 6;
+  RegionInfo *RI = R->getRegionInfo();
 
-      O.indent(2 * (depth + 1)) << "color = " << color << "\n";
-    }
+  for (BasicBlock *BB : R->blocks())
+    if (RI->getRegionFor(BB) == R)
+      O.indent(2 * (depth + 1))
+          << "Node"
+          << static_cast<void *>(RI->getTopLevelRegion()->getBBNode(BB))
+          << ";\n";
 
-    for (const auto &SubRegion : *R)
-      printRegionCluster(SD, SubRegion.get(), O, depth + 1);
+  O.indent(2 * depth) << "}\n";
+}
 
-    RegionInfo *RI = R->getRegionInfo();
+void DOTGraphTraits<ScopDetection *>::addCustomGraphFeatures(
+    ScopDetection *SD, GraphWriter<ScopDetection *> &GW) {
+  raw_ostream &O = GW.getOStream();
+  O << "\tcolorscheme = \"paired12\"\n";
+  printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4);
+}
 
-    for (BasicBlock *BB : R->blocks())
-      if (RI->getRegionFor(BB) == R)
-        O.indent(2 * (depth + 1))
-            << "Node"
-            << static_cast<void *>(RI->getTopLevelRegion()->getBBNode(BB))
-            << ";\n";
+} // namespace llvm
 
-    O.indent(2 * depth) << "}\n";
-  }
-  static void
-  addCustomGraphFeatures(const ScopDetectionWrapperPass *SD,
-                         GraphWriter<ScopDetectionWrapperPass *> &GW) {
-    raw_ostream &O = GW.getOStream();
-    O << "\tcolorscheme = \"paired12\"\n";
-    printRegionCluster(&SD->getSD(), SD->getSD().getRI()->getTopLevelRegion(),
-                       O, 4);
+struct ScopDetectionAnalysisGraphTraits {
+  static ScopDetection *getGraph(ScopDetectionWrapperPass *Analysis) {
+    return &Analysis->getSD();
   }
 };
-} // end namespace llvm
 
-struct ScopViewer
-    : public DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false> {
+struct ScopViewerWrapperPass
+    : public DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
+                                             ScopDetection *,
+                                             ScopDetectionAnalysisGraphTraits> {
   static char ID;
-  ScopViewer()
-      : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false>(
+  ScopViewerWrapperPass()
+      : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
+                                        ScopDetection *,
+                                        ScopDetectionAnalysisGraphTraits>(
             "scops", ID) {}
   bool processFunction(Function &F, ScopDetectionWrapperPass &SD) override {
     if (ViewFilter != "" && !F.getName().count(ViewFilter))
@@ -214,53 +161,84 @@ struct ScopViewer
     return std::distance(SD.getSD().begin(), SD.getSD().end()) > 0;
   }
 };
-char ScopViewer::ID = 0;
+char ScopViewerWrapperPass::ID = 0;
 
-struct ScopOnlyViewer
-    : public DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, true> {
+struct ScopOnlyViewerWrapperPass
+    : public DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
+                                             ScopDetection *,
+                                             ScopDetectionAnalysisGraphTraits> {
   static char ID;
-  ScopOnlyViewer()
-      : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, true>(
+  ScopOnlyViewerWrapperPass()
+      : DOTGraphTraitsViewerWrapperPass<ScopDetectionWrapperPass, false,
+                                        ScopDetection *,
+                                        ScopDetectionAnalysisGraphTraits>(
             "scopsonly", ID) {}
 };
-char ScopOnlyViewer::ID = 0;
+char ScopOnlyViewerWrapperPass::ID = 0;
 
-struct ScopPrinter
-    : public DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false> {
+struct ScopPrinterWrapperPass
+    : public DOTGraphTraitsPrinterWrapperPass<
+          ScopDetectionWrapperPass, false, ScopDetection *,
+          ScopDetectionAnalysisGraphTraits> {
   static char ID;
-  ScopPrinter()
-      : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false>(
+  ScopPrinterWrapperPass()
+      : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, false,
+                                         ScopDetection *,
+                                         ScopDetectionAnalysisGraphTraits>(
             "scops", ID) {}
 };
-char ScopPrinter::ID = 0;
+char ScopPrinterWrapperPass::ID = 0;
 
-struct ScopOnlyPrinter
-    : public DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true> {
+struct ScopOnlyPrinterWrapperPass
+    : public DOTGraphTraitsPrinterWrapperPass<
+          ScopDetectionWrapperPass, true, ScopDetection *,
+          ScopDetectionAnalysisGraphTraits> {
   static char ID;
-  ScopOnlyPrinter()
-      : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true>(
+  ScopOnlyPrinterWrapperPass()
+      : DOTGraphTraitsPrinterWrapperPass<ScopDetectionWrapperPass, true,
+                                         ScopDetection *,
+                                         ScopDetectionAnalysisGraphTraits>(
             "scopsonly", ID) {}
 };
-char ScopOnlyPrinter::ID = 0;
+char ScopOnlyPrinterWrapperPass::ID = 0;
 
-static RegisterPass<ScopViewer> X("view-scops",
-                                  "Polly - View Scops of function");
+static RegisterPass<ScopViewerWrapperPass> X("view-scops",
+                                             "Polly - View Scops of function");
 
-static RegisterPass<ScopOnlyViewer>
+static RegisterPass<ScopOnlyViewerWrapperPass>
     Y("view-scops-only",
       "Polly - View Scops of function (with no function bodies)");
 
-static RegisterPass<ScopPrinter> M("dot-scops",
-                                   "Polly - Print Scops of function");
+static RegisterPass<ScopPrinterWrapperPass>
+    M("dot-scops", "Polly - Print Scops of function");
 
-static RegisterPass<ScopOnlyPrinter>
+static RegisterPass<ScopOnlyPrinterWrapperPass>
     N("dot-scops-only",
       "Polly - Print Scops of function (with no function bodies)");
 
-Pass *polly::createDOTViewerPass() { return new ScopViewer(); }
+Pass *polly::createDOTViewerWrapperPass() {
+  return new ScopViewerWrapperPass();
+}
+
+Pass *polly::createDOTOnlyViewerWrapperPass() {
+  return new ScopOnlyViewerWrapperPass();
+}
+
+Pass *polly::createDOTPrinterWrapperPass() {
+  return new ScopPrinterWrapperPass();
+}
+
+Pass *polly::createDOTOnlyPrinterWrapperPass() {
+  return new ScopOnlyPrinterWrapperPass();
+}
 
-Pass *polly::createDOTOnlyViewerPass() { return new ScopOnlyViewer(); }
+bool ScopViewer::processFunction(Function &F, const ScopDetection &SD) {
+  if (ViewFilter != "" && !F.getName().count(ViewFilter))
+    return false;
 
-Pass *polly::createDOTPrinterPass() { return new ScopPrinter(); }
+  if (ViewAll)
+    return true;
 
-Pass *polly::createDOTOnlyPrinterPass() { return new ScopOnlyPrinter(); }
+  // Check that at least one scop was detected.
+  return std::distance(SD.begin(), SD.end()) > 0;
+}

diff  --git a/polly/lib/Support/PollyPasses.def b/polly/lib/Support/PollyPasses.def
index 76729b6a382e9..9eb667b98cffa 100644
--- a/polly/lib/Support/PollyPasses.def
+++ b/polly/lib/Support/PollyPasses.def
@@ -11,6 +11,10 @@ FUNCTION_ANALYSIS("polly-function-scops", ScopInfoAnalysis())
 FUNCTION_PASS("polly-prepare", CodePreparationPass())
 FUNCTION_PASS("print<polly-detect>", ScopAnalysisPrinterPass(llvm::errs()))
 FUNCTION_PASS("print<polly-function-scops>", ScopInfoPrinterPass(llvm::errs()))
+FUNCTION_PASS("polly-scop-viewer", ScopViewer())
+FUNCTION_PASS("polly-scop-only-viewer", ScopOnlyViewer())
+FUNCTION_PASS("polly-scop-printer", ScopPrinter())
+FUNCTION_PASS("polly-scop-only-printer", ScopOnlyPrinter())
 #undef FUNCTION_PASS
 
 #ifndef SCOP_ANALYSIS

diff  --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp
index 7e9edf54adb70..ef52adf56019b 100644
--- a/polly/lib/Support/RegisterPasses.cpp
+++ b/polly/lib/Support/RegisterPasses.cpp
@@ -34,6 +34,7 @@
 #include "polly/PruneUnprofitable.h"
 #include "polly/ScheduleOptimizer.h"
 #include "polly/ScopDetection.h"
+#include "polly/ScopGraphPrinter.h"
 #include "polly/ScopInfo.h"
 #include "polly/Simplify.h"
 #include "polly/Support/DumpFunctionPass.h"
@@ -331,14 +332,13 @@ static void registerPollyPasses(llvm::legacy::PassManagerBase &PM,
     return;
 
   if (PollyViewer)
-    PM.add(polly::createDOTViewerPass());
+    PM.add(polly::createDOTViewerWrapperPass());
   if (PollyOnlyViewer)
-    PM.add(polly::createDOTOnlyViewerPass());
+    PM.add(polly::createDOTOnlyViewerWrapperPass());
   if (PollyPrinter)
-    PM.add(polly::createDOTPrinterPass());
+    PM.add(polly::createDOTPrinterWrapperPass());
   if (PollyOnlyPrinter)
-    PM.add(polly::createDOTOnlyPrinterPass());
-
+    PM.add(polly::createDOTOnlyPrinterWrapperPass());
   PM.add(polly::createScopInfoRegionPassPass());
   if (EnablePolyhedralInfo)
     PM.add(polly::createPolyhedralInfoPass());
@@ -509,16 +509,13 @@ static void buildCommonPollyPipeline(FunctionPassManager &PM,
   }
 
   if (PollyViewer)
-    llvm::report_fatal_error("Option -polly-show not supported with NPM",
-                             false);
+    PM.addPass(ScopViewer());
   if (PollyOnlyViewer)
-    llvm::report_fatal_error("Option -polly-show-only not supported with NPM",
-                             false);
+    PM.addPass(ScopOnlyViewer());
   if (PollyPrinter)
-    llvm::report_fatal_error("Option -polly-dot not supported with NPM", false);
+    PM.addPass(ScopPrinter());
   if (PollyOnlyPrinter)
-    llvm::report_fatal_error("Option -polly-dot-only not supported with NPM",
-                             false);
+    PM.addPass(ScopOnlyPrinter());
   if (EnablePolyhedralInfo)
     llvm::report_fatal_error(
         "Option -polly-enable-polyhedralinfo not supported with NPM", false);

diff  --git a/polly/test/ScopDetect/dot-scops-npm.ll b/polly/test/ScopDetect/dot-scops-npm.ll
new file mode 100644
index 0000000000000..3a72d24ffd401
--- /dev/null
+++ b/polly/test/ScopDetect/dot-scops-npm.ll
@@ -0,0 +1,100 @@
+; RUN: opt %loadPolly "-passes=polly-scop-printer" -disable-output < %s
+; RUN: FileCheck %s -input-file=scops.func.dot
+;
+; Check that the ScopPrinter does not crash.
+; ScopPrinter needs the ScopDetection pass, which should depend on
+; ScalarEvolution transitively.
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @func(i32 %n, i32 %m, double* noalias nonnull %A) {
+; CHECK:      digraph "Scop Graph for 'func' function"
+; CHECK-NEXT: label="Scop Graph for 'func' function"
+; CHECK:      Node0x[[EntryID:.*]] [shape=record,label="{entry:\l  br label %outer.for\l}"];
+; CHECK-NEXT: Node0x[[EntryID]] -> Node0x[[OUTER_FOR_ID:.*]];
+; CHECK-NEXT: Node0x[[OUTER_FOR_ID]] [shape=record,label="{outer.for:
+; CHECK-NEXT: Node0x[[OUTER_FOR_ID]] -> Node0x[[INNER_FOR_ID:.*]];
+; CHECK-NEXT: Node0x[[OUTER_FOR_ID]] -> Node0x[[OUTER_EXIT:.*]];
+; CHECK-NEXT: Node0x[[INNER_FOR_ID]] [shape=record,label="{inner.for:
+; CHECK-NEXT: Node0x[[INNER_FOR_ID]] -> Node0x[[BABY1_ID:.*]];
+; CHECK-NEXT: Node0x[[INNER_FOR_ID]] -> Node0x[[INNER_EXIT_ID:.*]];
+; CHECK-NEXT: Node0x[[BABY1_ID]] [shape=record,label="{body1:
+; CHECK-NEXT: Node0x[[BABY1_ID]] -> Node0x[[INNER_INC_ID:.*]];
+; CHECK-NEXT: Node0x[[INNER_INC_ID]] [shape=record,label="{inner.inc:
+; CHECK-NEXT: Node0x[[INNER_INC_ID]] -> Node0x[[INNER_FOR_ID]][constraint=false];
+; CHECK-NEXT: Node0x[[INNER_EXIT_ID]] [shape=record,label="{inner.exit:
+; CHECK-NEXT: Node0x[[INNER_EXIT_ID]] -> Node0x[[OUTER_INC_ID:.*]];
+; CHECK-NEXT: Node0x[[OUTER_INC_ID]] [shape=record,label="{outer.inc:
+; CHECK-NEXT: Node0x[[OUTER_INC_ID]] -> Node0x[[OUTER_FOR_ID]][constraint=false];
+; CHECK-NEXT: Node0x[[OUTER_EXIT]] [shape=record,label="{outer.exit:
+; CHECK-NEXT: Node0x[[OUTER_EXIT]] -> Node0x[[RETURN_ID:.*]];
+; CHECK-NEXT: Node0x[[RETURN_ID]] [shape=record,label="{return:
+; CHECK-NEXT: colorscheme = "paired12"
+; CHECK_NEXT: subgraph cluster_0x[[:.*]] {
+; CHECK_NEXT: label = "";
+; CHECK_NEXT: style = solid;
+; CHECK_NEXT: color = 1
+; CHECK_NEXT: subgraph cluster_0x[[:.*]] {
+; CHECK_NEXT: label = "";
+; CHECK_NEXT: style = filled;
+; CHECK_NEXT: color = 3            subgraph cluster_0x7152c40 {
+; CHECK_NEXT: label = "";
+; CHECK_NEXT: style = solid;
+; CHECK_NEXT: color = 5
+; CHECK_NEXT: subgraph cluster_0x[[:.*]] {
+; CHECK_NEXT: label = "";
+; CHECK_NEXT: style = solid;
+; CHECK_NEXT: color = 7
+; CHECK_NEXT: Node0x[[INNER_FOR_ID]];
+; CHECK_NEXT: Node0x[[BABY1_ID]];
+; CHECK_NEXT: Node0x[[INNER_INC_ID]];
+; CHECK_NEXT: }
+; CHECK_NEXT: Node0x[[OUTER_FOR_ID]];
+; CHECK_NEXT: Node0x[[INNER_EXIT_ID]];
+; CHECK_NEXT: Node0x[[OUTER_INC_ID]];
+; CHECK_NEXT: }
+; CHECK_NEXT: Node0x[[OUTER_EXIT]];
+; CHECK_NEXT: }
+; CHECK_NEXT: Node0x[[EntryID]];
+; CHECK_NEXT: Node0x[[RETURN_ID]];
+; CHECK_NEXT: }
+; CHECK_NEXT: }
+
+entry:
+  br label %outer.for
+
+outer.for:
+  %j = phi i32 [0, %entry], [%j.inc, %outer.inc]
+  %j.cmp = icmp slt i32 %j, %n
+  br i1 %j.cmp, label %inner.for, label %outer.exit
+
+  inner.for:
+    %i = phi i32 [1, %outer.for], [%i.inc, %inner.inc]
+    %b = phi double [0.0, %outer.for], [%a, %inner.inc]
+    %i.cmp = icmp slt i32 %i, %m
+    br i1 %i.cmp, label %body1, label %inner.exit
+
+    body1:
+      %A_idx = getelementptr inbounds double, double* %A, i32 %i
+      %a = load double, double* %A_idx
+      store double %a, double* %A_idx
+      br label %inner.inc
+
+  inner.inc:
+    %i.inc = add nuw nsw i32 %i, 1
+    br label %inner.for
+
+  inner.exit:
+    br label %outer.inc
+
+outer.inc:
+  store double %b, double* %A
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %outer.for
+
+outer.exit:
+  br label %return
+
+return:
+  ret void
+}


        


More information about the llvm-commits mailing list