[polly] r310597 - [JSON][PM] Port json import/export over to new pm

Philip Pfaffe via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 10 07:45:09 PDT 2017


Author: pfaffe
Date: Thu Aug 10 07:45:09 2017
New Revision: 310597

URL: http://llvm.org/viewvc/llvm-project?rev=310597&view=rev
Log:
[JSON][PM] Port json import/export over to new pm

Summary:
I pulled out all functionality into static functions, and use those both
in the legacy passes and in the new ones.

Reviewers: grosser, Meinersbur, bollu

Reviewed By: Meinersbur

Subscribers: llvm-commits, pollydev

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

Added:
    polly/trunk/include/polly/JSONExporter.h
Modified:
    polly/trunk/lib/Exchange/JSONExporter.cpp
    polly/trunk/lib/Support/PollyPasses.def
    polly/trunk/lib/Support/RegisterPasses.cpp

Added: polly/trunk/include/polly/JSONExporter.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/JSONExporter.h?rev=310597&view=auto
==============================================================================
--- polly/trunk/include/polly/JSONExporter.h (added)
+++ polly/trunk/include/polly/JSONExporter.h Thu Aug 10 07:45:09 2017
@@ -0,0 +1,23 @@
+#ifndef POLLY_JSONEXPORTER_H
+#define POLLY_JSONEXPORTER_H
+
+#include "polly/ScopPass.h"
+#include "llvm/IR/PassManager.h"
+
+namespace polly {
+/// This pass exports a scop to a jscop file. The filename is generated from the
+/// concatenation of the function and scop name.
+struct JSONExportPass : public llvm::PassInfoMixin<JSONExportPass> {
+  llvm::PreservedAnalyses run(Scop &, ScopAnalysisManager &,
+                              ScopStandardAnalysisResults &, SPMUpdater &);
+};
+
+/// This pass imports a scop from a jscop file. The filename is deduced from the
+/// concatenation of the function and scop name.
+struct JSONImportPass : public llvm::PassInfoMixin<JSONExportPass> {
+  llvm::PreservedAnalyses run(Scop &, ScopAnalysisManager &,
+                              ScopStandardAnalysisResults &, SPMUpdater &);
+};
+} // namespace polly
+
+#endif /* POLLY_JSONEXPORTER_H */

Modified: polly/trunk/lib/Exchange/JSONExporter.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Exchange/JSONExporter.cpp?rev=310597&r1=310596&r2=310597&view=diff
==============================================================================
--- polly/trunk/lib/Exchange/JSONExporter.cpp (original)
+++ polly/trunk/lib/Exchange/JSONExporter.cpp Thu Aug 10 07:45:09 2017
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "polly/JSONExporter.h"
 #include "polly/DependenceInfo.h"
 #include "polly/LinkAllPasses.h"
 #include "polly/Options.h"
@@ -59,9 +60,6 @@ struct JSONExporter : public ScopPass {
   static char ID;
   explicit JSONExporter() : ScopPass(ID) {}
 
-  std::string getFileName(Scop &S) const;
-  Json::Value getJSON(Scop &S) const;
-
   /// Export the SCoP @p S to a JSON file.
   bool runOnScop(Scop &S) override;
 
@@ -76,46 +74,6 @@ struct JSONImporter : public ScopPass {
   static char ID;
   std::vector<std::string> NewAccessStrings;
   explicit JSONImporter() : ScopPass(ID) {}
-
-  /// Import a new context from JScop.
-  ///
-  /// @param S The scop to update.
-  /// @param JScop The JScop file describing the new schedule.
-  ///
-  /// @returns True if the import succeeded, otherwise False.
-  bool importContext(Scop &S, Json::Value &JScop);
-
-  /// Import a new schedule from JScop.
-  ///
-  /// ... and verify that the new schedule does preserve existing data
-  /// dependences.
-  ///
-  /// @param S The scop to update.
-  /// @param JScop The JScop file describing the new schedule.
-  /// @param D The data dependences of the @p S.
-  ///
-  /// @returns True if the import succeeded, otherwise False.
-  bool importSchedule(Scop &S, Json::Value &JScop, const Dependences &D);
-
-  /// Import new arrays from JScop.
-  ///
-  /// @param S The scop to update.
-  /// @param JScop The JScop file describing new arrays.
-  ///
-  /// @returns True if the import succeeded, otherwise False.
-  bool importArrays(Scop &S, Json::Value &JScop);
-
-  /// Import new memory accesses from JScop.
-  ///
-  /// @param S The scop to update.
-  /// @param JScop The JScop file describing the new schedule.
-  /// @param DL The data layout to assume.
-  ///
-  /// @returns True if the import succeeded, otherwise False.
-  bool importAccesses(Scop &S, Json::Value &JScop, const DataLayout &DL);
-
-  std::string getFileName(Scop &S) const;
-
   /// Import new access functions for SCoP @p S from a JSON file.
   bool runOnScop(Scop &S) override;
 
@@ -127,21 +85,22 @@ struct JSONImporter : public ScopPass {
 };
 } // namespace
 
-char JSONExporter::ID = 0;
-std::string JSONExporter::getFileName(Scop &S) const {
+static std::string getFileName(Scop &S, StringRef Suffix = "") {
   std::string FunctionName = S.getFunction().getName();
   std::string FileName = FunctionName + "___" + S.getNameStr() + ".jscop";
+
+  if (Suffix != "")
+    FileName += "." + Suffix.str();
+
   return FileName;
 }
 
-void JSONExporter::printScop(raw_ostream &OS, Scop &S) const { OS << S; }
-
 /// Export all arrays from the Scop.
 ///
 /// @param S The Scop containing the arrays.
 ///
 /// @returns Json::Value containing the arrays.
-Json::Value exportArrays(const Scop &S) {
+static Json::Value exportArrays(const Scop &S) {
   Json::Value Arrays;
   std::string Buffer;
   llvm::raw_string_ostream RawStringOstream(Buffer);
@@ -170,7 +129,7 @@ Json::Value exportArrays(const Scop &S)
   return Arrays;
 }
 
-Json::Value JSONExporter::getJSON(Scop &S) const {
+static Json::Value getJSON(Scop &S) {
   Json::Value root;
   unsigned LineBegin, LineEnd;
   std::string FileName;
@@ -213,7 +172,7 @@ Json::Value JSONExporter::getJSON(Scop &
   return root;
 }
 
-bool JSONExporter::runOnScop(Scop &S) {
+static void exportScop(Scop &S) {
   std::string FileName = ImportDir + "/" + getFileName(S);
 
   Json::Value jscop = getJSON(S);
@@ -234,45 +193,23 @@ bool JSONExporter::runOnScop(Scop &S) {
     if (!F.os().has_error()) {
       errs() << "\n";
       F.keep();
-      return false;
+      return;
     }
   }
 
   errs() << "  error opening file for writing!\n";
   F.os().clear_error();
-
-  return false;
-}
-
-void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const {
-  AU.setPreservesAll();
-  AU.addRequired<ScopInfoRegionPass>();
-}
-
-Pass *polly::createJSONExporterPass() { return new JSONExporter(); }
-
-char JSONImporter::ID = 0;
-std::string JSONImporter::getFileName(Scop &S) const {
-  std::string FunctionName = S.getFunction().getName();
-  std::string FileName = FunctionName + "___" + S.getNameStr() + ".jscop";
-
-  if (ImportPostfix != "")
-    FileName += "." + ImportPostfix;
-
-  return FileName;
-}
-
-void JSONImporter::printScop(raw_ostream &OS, Scop &S) const {
-  OS << S;
-  for (std::vector<std::string>::const_iterator I = NewAccessStrings.begin(),
-                                                E = NewAccessStrings.end();
-       I != E; I++)
-    OS << "New access function '" << *I << "' detected in JSCOP file\n";
 }
 
 typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
 
-bool JSONImporter::importContext(Scop &S, Json::Value &JScop) {
+/// Import a new context from JScop.
+///
+/// @param S The scop to update.
+/// @param JScop The JScop file describing the new schedule.
+///
+/// @returns True if the import succeeded, otherwise False.
+static bool importContext(Scop &S, Json::Value &JScop) {
   isl_set *OldContext = S.getContext().release();
 
   // Check if key 'context' is present.
@@ -324,8 +261,17 @@ bool JSONImporter::importContext(Scop &S
   return true;
 }
 
-bool JSONImporter::importSchedule(Scop &S, Json::Value &JScop,
-                                  const Dependences &D) {
+/// Import a new schedule from JScop.
+///
+/// ... and verify that the new schedule does preserve existing data
+/// dependences.
+///
+/// @param S The scop to update.
+/// @param JScop The JScop file describing the new schedule.
+/// @param D The data dependences of the @p S.
+///
+/// @returns True if the import succeeded, otherwise False.
+static bool importSchedule(Scop &S, Json::Value &JScop, const Dependences &D) {
   StatementToIslMapTy NewSchedule;
 
   // Check if key 'statements' is present.
@@ -405,8 +351,17 @@ bool JSONImporter::importSchedule(Scop &
   return true;
 }
 
-bool JSONImporter::importAccesses(Scop &S, Json::Value &JScop,
-                                  const DataLayout &DL) {
+/// Import new memory accesses from JScop.
+///
+/// @param S The scop to update.
+/// @param JScop The JScop file describing the new schedule.
+/// @param DL The data layout to assume.
+/// @param NewAccessStrings optionally record the imported access strings
+///
+/// @returns True if the import succeeded, otherwise False.
+static bool
+importAccesses(Scop &S, Json::Value &JScop, const DataLayout &DL,
+               std::vector<std::string> *NewAccessStrings = nullptr) {
   int StatementIdx = 0;
 
   // Check if key 'statements' is present.
@@ -582,7 +537,8 @@ bool JSONImporter::importAccesses(Scop &
       if (!isl_map_is_equal(NewAccessMap, CurrentAccessMap)) {
         // Statistics.
         ++NewAccessMapFound;
-        NewAccessStrings.push_back(Accesses.asCString());
+        if (NewAccessStrings)
+          NewAccessStrings->push_back(Accesses.asCString());
         MA->setNewAccessRelation(isl::manage(NewAccessMap));
       } else {
         isl_map_free(NewAccessMap);
@@ -597,7 +553,7 @@ bool JSONImporter::importAccesses(Scop &
 }
 
 /// Check whether @p SAI and @p Array represent the same array.
-bool areArraysEqual(ScopArrayInfo *SAI, Json::Value Array) {
+static bool areArraysEqual(ScopArrayInfo *SAI, Json::Value Array) {
   std::string Buffer;
   llvm::raw_string_ostream RawStringOstream(Buffer);
 
@@ -648,8 +604,8 @@ bool areArraysEqual(ScopArrayInfo *SAI,
 /// @param TypeTextRepresentation The textual representation of the type.
 /// @return The pointer to the primitive type, if this type is accepted
 ///         or nullptr otherwise.
-Type *parseTextType(const std::string &TypeTextRepresentation,
-                    LLVMContext &LLVMContext) {
+static Type *parseTextType(const std::string &TypeTextRepresentation,
+                           LLVMContext &LLVMContext) {
   std::map<std::string, Type *> MapStrToType = {
       {"void", Type::getVoidTy(LLVMContext)},
       {"half", Type::getHalfTy(LLVMContext)},
@@ -674,7 +630,13 @@ Type *parseTextType(const std::string &T
   return nullptr;
 }
 
-bool JSONImporter::importArrays(Scop &S, Json::Value &JScop) {
+/// Import new arrays from JScop.
+///
+/// @param S The scop to update.
+/// @param JScop The JScop file describing new arrays.
+///
+/// @returns True if the import succeeded, otherwise False.
+static bool importArrays(Scop &S, Json::Value &JScop) {
   Json::Value Arrays = JScop["arrays"];
   if (Arrays.size() == 0)
     return true;
@@ -726,12 +688,18 @@ bool JSONImporter::importArrays(Scop &S,
   return true;
 }
 
-bool JSONImporter::runOnScop(Scop &S) {
-  const Dependences &D =
-      getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
-  const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
-
-  std::string FileName = ImportDir + "/" + getFileName(S);
+/// Import a Scop from a JSCOP file
+/// @param S The scop to be modified
+/// @param D Dependence Info
+/// @param DL The DataLayout of the function
+/// @param NewAccessStrings Optionally record the imported access strings
+///
+/// @returns true on success, false otherwise. Beware that if this returns
+/// false, the Scop may still have been modified. In this case the Scop contains
+/// invalid information.
+static bool importScop(Scop &S, const Dependences &D, const DataLayout &DL,
+                       std::vector<std::string> *NewAccessStrings = nullptr) {
+  std::string FileName = ImportDir + "/" + getFileName(S, ImportPostfix);
 
   std::string FunctionName = S.getFunction().getName();
   errs() << "Reading JScop '" << S.getNameStr() << "' in function '"
@@ -770,11 +738,50 @@ bool JSONImporter::runOnScop(Scop &S) {
   if (!Success)
     return false;
 
-  Success = importAccesses(S, jscop, DL);
+  Success = importAccesses(S, jscop, DL, NewAccessStrings);
 
   if (!Success)
     return false;
+  return true;
+}
+
+char JSONExporter::ID = 0;
+void JSONExporter::printScop(raw_ostream &OS, Scop &S) const { OS << S; }
 
+bool JSONExporter::runOnScop(Scop &S) {
+  exportScop(S);
+  return false;
+}
+
+void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.setPreservesAll();
+  AU.addRequired<ScopInfoRegionPass>();
+}
+
+Pass *polly::createJSONExporterPass() { return new JSONExporter(); }
+
+PreservedAnalyses JSONExportPass::run(Scop &S, ScopAnalysisManager &SAM,
+                                      ScopStandardAnalysisResults &SAR,
+                                      SPMUpdater &) {
+  exportScop(S);
+  return PreservedAnalyses::all();
+}
+
+char JSONImporter::ID = 0;
+
+void JSONImporter::printScop(raw_ostream &OS, Scop &S) const {
+  OS << S;
+  for (std::vector<std::string>::const_iterator I = NewAccessStrings.begin(),
+                                                E = NewAccessStrings.end();
+       I != E; I++)
+    OS << "New access function '" << *I << "' detected in JSCOP file\n";
+}
+
+bool JSONImporter::runOnScop(Scop &S) {
+  const Dependences &D =
+      getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
+  const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
+  importScop(S, D, DL, &NewAccessStrings);
   return false;
 }
 
@@ -785,6 +792,24 @@ void JSONImporter::getAnalysisUsage(Anal
 
 Pass *polly::createJSONImporterPass() { return new JSONImporter(); }
 
+PreservedAnalyses JSONImportPass::run(Scop &S, ScopAnalysisManager &SAM,
+                                      ScopStandardAnalysisResults &SAR,
+                                      SPMUpdater &) {
+  const Dependences &D =
+      SAM.getResult<DependenceAnalysis>(S, SAR).getDependences(
+          Dependences::AL_Statement);
+  const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
+
+  importScop(S, D, DL);
+
+  // This invalidates all analyses on Scop.
+  PreservedAnalyses PA;
+  PA.preserveSet<AllAnalysesOn<Module>>();
+  PA.preserveSet<AllAnalysesOn<Function>>();
+  PA.preserveSet<AllAnalysesOn<Loop>>();
+  return PA;
+}
+
 INITIALIZE_PASS_BEGIN(JSONExporter, "polly-export-jscop",
                       "Polly - Export Scops as JSON"
                       " (Writes a .jscop file for each Scop)",

Modified: polly/trunk/lib/Support/PollyPasses.def
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/PollyPasses.def?rev=310597&r1=310596&r2=310597&view=diff
==============================================================================
--- polly/trunk/lib/Support/PollyPasses.def (original)
+++ polly/trunk/lib/Support/PollyPasses.def Thu Aug 10 07:45:09 2017
@@ -23,6 +23,8 @@ SCOP_ANALYSIS("polly-dependences", Depen
 #ifndef SCOP_PASS
 #define SCOP_PASS(NAME, CREATE_PASS)
 #endif
+SCOP_PASS("polly-export-jscop", JSONExportPass())
+SCOP_PASS("polly-import-jscop", JSONImportPass())
 SCOP_PASS("print<polly-ast>", IslAstPrinterPass(outs()))
 SCOP_PASS("print<polly-dependences>", DependenceInfoPrinterPass(outs()))
 SCOP_PASS("polly-codegen", CodeGenerationPass())

Modified: polly/trunk/lib/Support/RegisterPasses.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/RegisterPasses.cpp?rev=310597&r1=310596&r2=310597&view=diff
==============================================================================
--- polly/trunk/lib/Support/RegisterPasses.cpp (original)
+++ polly/trunk/lib/Support/RegisterPasses.cpp Thu Aug 10 07:45:09 2017
@@ -30,6 +30,7 @@
 #include "polly/DependenceInfo.h"
 #include "polly/FlattenSchedule.h"
 #include "polly/ForwardOpTree.h"
+#include "polly/JSONExporter.h"
 #include "polly/LinkAllPasses.h"
 #include "polly/Options.h"
 #include "polly/PolyhedralInfo.h"
@@ -473,7 +474,8 @@ static void buildDefaultPollyPipeline(Fu
   assert(!EnablePolyhedralInfo && "This option is not implemented");
   assert(!EnableDeLICM && "This option is not implemented");
   assert(!EnableSimplify && "This option is not implemented");
-  assert(!ImportJScop && "This option is not implemented");
+  if (ImportJScop)
+    SPM.addPass(JSONImportPass());
   assert(!DeadCodeElim && "This option is not implemented");
   assert(!EnablePruneUnprofitable && "This option is not implemented");
   if (Target == TARGET_CPU || Target == TARGET_HYBRID)




More information about the llvm-commits mailing list