[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