[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