Skip to content

Commit 47bf15c

Browse files
committedAug 10, 2017
[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 llvm-svn: 310597
1 parent 925c074 commit 47bf15c

File tree

4 files changed

+149
-97
lines changed

4 files changed

+149
-97
lines changed
 

‎polly/include/polly/JSONExporter.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef POLLY_JSONEXPORTER_H
2+
#define POLLY_JSONEXPORTER_H
3+
4+
#include "polly/ScopPass.h"
5+
#include "llvm/IR/PassManager.h"
6+
7+
namespace polly {
8+
/// This pass exports a scop to a jscop file. The filename is generated from the
9+
/// concatenation of the function and scop name.
10+
struct JSONExportPass : public llvm::PassInfoMixin<JSONExportPass> {
11+
llvm::PreservedAnalyses run(Scop &, ScopAnalysisManager &,
12+
ScopStandardAnalysisResults &, SPMUpdater &);
13+
};
14+
15+
/// This pass imports a scop from a jscop file. The filename is deduced from the
16+
/// concatenation of the function and scop name.
17+
struct JSONImportPass : public llvm::PassInfoMixin<JSONExportPass> {
18+
llvm::PreservedAnalyses run(Scop &, ScopAnalysisManager &,
19+
ScopStandardAnalysisResults &, SPMUpdater &);
20+
};
21+
} // namespace polly
22+
23+
#endif /* POLLY_JSONEXPORTER_H */

‎polly/lib/Exchange/JSONExporter.cpp

+121-96
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "polly/JSONExporter.h"
1415
#include "polly/DependenceInfo.h"
1516
#include "polly/LinkAllPasses.h"
1617
#include "polly/Options.h"
@@ -59,9 +60,6 @@ struct JSONExporter : public ScopPass {
5960
static char ID;
6061
explicit JSONExporter() : ScopPass(ID) {}
6162

62-
std::string getFileName(Scop &S) const;
63-
Json::Value getJSON(Scop &S) const;
64-
6563
/// Export the SCoP @p S to a JSON file.
6664
bool runOnScop(Scop &S) override;
6765

@@ -76,46 +74,6 @@ struct JSONImporter : public ScopPass {
7674
static char ID;
7775
std::vector<std::string> NewAccessStrings;
7876
explicit JSONImporter() : ScopPass(ID) {}
79-
80-
/// Import a new context from JScop.
81-
///
82-
/// @param S The scop to update.
83-
/// @param JScop The JScop file describing the new schedule.
84-
///
85-
/// @returns True if the import succeeded, otherwise False.
86-
bool importContext(Scop &S, Json::Value &JScop);
87-
88-
/// Import a new schedule from JScop.
89-
///
90-
/// ... and verify that the new schedule does preserve existing data
91-
/// dependences.
92-
///
93-
/// @param S The scop to update.
94-
/// @param JScop The JScop file describing the new schedule.
95-
/// @param D The data dependences of the @p S.
96-
///
97-
/// @returns True if the import succeeded, otherwise False.
98-
bool importSchedule(Scop &S, Json::Value &JScop, const Dependences &D);
99-
100-
/// Import new arrays from JScop.
101-
///
102-
/// @param S The scop to update.
103-
/// @param JScop The JScop file describing new arrays.
104-
///
105-
/// @returns True if the import succeeded, otherwise False.
106-
bool importArrays(Scop &S, Json::Value &JScop);
107-
108-
/// Import new memory accesses from JScop.
109-
///
110-
/// @param S The scop to update.
111-
/// @param JScop The JScop file describing the new schedule.
112-
/// @param DL The data layout to assume.
113-
///
114-
/// @returns True if the import succeeded, otherwise False.
115-
bool importAccesses(Scop &S, Json::Value &JScop, const DataLayout &DL);
116-
117-
std::string getFileName(Scop &S) const;
118-
11977
/// Import new access functions for SCoP @p S from a JSON file.
12078
bool runOnScop(Scop &S) override;
12179

@@ -127,21 +85,22 @@ struct JSONImporter : public ScopPass {
12785
};
12886
} // namespace
12987

130-
char JSONExporter::ID = 0;
131-
std::string JSONExporter::getFileName(Scop &S) const {
88+
static std::string getFileName(Scop &S, StringRef Suffix = "") {
13289
std::string FunctionName = S.getFunction().getName();
13390
std::string FileName = FunctionName + "___" + S.getNameStr() + ".jscop";
91+
92+
if (Suffix != "")
93+
FileName += "." + Suffix.str();
94+
13495
return FileName;
13596
}
13697

137-
void JSONExporter::printScop(raw_ostream &OS, Scop &S) const { OS << S; }
138-
13998
/// Export all arrays from the Scop.
14099
///
141100
/// @param S The Scop containing the arrays.
142101
///
143102
/// @returns Json::Value containing the arrays.
144-
Json::Value exportArrays(const Scop &S) {
103+
static Json::Value exportArrays(const Scop &S) {
145104
Json::Value Arrays;
146105
std::string Buffer;
147106
llvm::raw_string_ostream RawStringOstream(Buffer);
@@ -170,7 +129,7 @@ Json::Value exportArrays(const Scop &S) {
170129
return Arrays;
171130
}
172131

173-
Json::Value JSONExporter::getJSON(Scop &S) const {
132+
static Json::Value getJSON(Scop &S) {
174133
Json::Value root;
175134
unsigned LineBegin, LineEnd;
176135
std::string FileName;
@@ -213,7 +172,7 @@ Json::Value JSONExporter::getJSON(Scop &S) const {
213172
return root;
214173
}
215174

216-
bool JSONExporter::runOnScop(Scop &S) {
175+
static void exportScop(Scop &S) {
217176
std::string FileName = ImportDir + "/" + getFileName(S);
218177

219178
Json::Value jscop = getJSON(S);
@@ -234,45 +193,23 @@ bool JSONExporter::runOnScop(Scop &S) {
234193
if (!F.os().has_error()) {
235194
errs() << "\n";
236195
F.keep();
237-
return false;
196+
return;
238197
}
239198
}
240199

241200
errs() << " error opening file for writing!\n";
242201
F.os().clear_error();
243-
244-
return false;
245-
}
246-
247-
void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const {
248-
AU.setPreservesAll();
249-
AU.addRequired<ScopInfoRegionPass>();
250-
}
251-
252-
Pass *polly::createJSONExporterPass() { return new JSONExporter(); }
253-
254-
char JSONImporter::ID = 0;
255-
std::string JSONImporter::getFileName(Scop &S) const {
256-
std::string FunctionName = S.getFunction().getName();
257-
std::string FileName = FunctionName + "___" + S.getNameStr() + ".jscop";
258-
259-
if (ImportPostfix != "")
260-
FileName += "." + ImportPostfix;
261-
262-
return FileName;
263-
}
264-
265-
void JSONImporter::printScop(raw_ostream &OS, Scop &S) const {
266-
OS << S;
267-
for (std::vector<std::string>::const_iterator I = NewAccessStrings.begin(),
268-
E = NewAccessStrings.end();
269-
I != E; I++)
270-
OS << "New access function '" << *I << "' detected in JSCOP file\n";
271202
}
272203

273204
typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
274205

275-
bool JSONImporter::importContext(Scop &S, Json::Value &JScop) {
206+
/// Import a new context from JScop.
207+
///
208+
/// @param S The scop to update.
209+
/// @param JScop The JScop file describing the new schedule.
210+
///
211+
/// @returns True if the import succeeded, otherwise False.
212+
static bool importContext(Scop &S, Json::Value &JScop) {
276213
isl_set *OldContext = S.getContext().release();
277214

278215
// Check if key 'context' is present.
@@ -324,8 +261,17 @@ bool JSONImporter::importContext(Scop &S, Json::Value &JScop) {
324261
return true;
325262
}
326263

327-
bool JSONImporter::importSchedule(Scop &S, Json::Value &JScop,
328-
const Dependences &D) {
264+
/// Import a new schedule from JScop.
265+
///
266+
/// ... and verify that the new schedule does preserve existing data
267+
/// dependences.
268+
///
269+
/// @param S The scop to update.
270+
/// @param JScop The JScop file describing the new schedule.
271+
/// @param D The data dependences of the @p S.
272+
///
273+
/// @returns True if the import succeeded, otherwise False.
274+
static bool importSchedule(Scop &S, Json::Value &JScop, const Dependences &D) {
329275
StatementToIslMapTy NewSchedule;
330276

331277
// Check if key 'statements' is present.
@@ -405,8 +351,17 @@ bool JSONImporter::importSchedule(Scop &S, Json::Value &JScop,
405351
return true;
406352
}
407353

408-
bool JSONImporter::importAccesses(Scop &S, Json::Value &JScop,
409-
const DataLayout &DL) {
354+
/// Import new memory accesses from JScop.
355+
///
356+
/// @param S The scop to update.
357+
/// @param JScop The JScop file describing the new schedule.
358+
/// @param DL The data layout to assume.
359+
/// @param NewAccessStrings optionally record the imported access strings
360+
///
361+
/// @returns True if the import succeeded, otherwise False.
362+
static bool
363+
importAccesses(Scop &S, Json::Value &JScop, const DataLayout &DL,
364+
std::vector<std::string> *NewAccessStrings = nullptr) {
410365
int StatementIdx = 0;
411366

412367
// Check if key 'statements' is present.
@@ -582,7 +537,8 @@ bool JSONImporter::importAccesses(Scop &S, Json::Value &JScop,
582537
if (!isl_map_is_equal(NewAccessMap, CurrentAccessMap)) {
583538
// Statistics.
584539
++NewAccessMapFound;
585-
NewAccessStrings.push_back(Accesses.asCString());
540+
if (NewAccessStrings)
541+
NewAccessStrings->push_back(Accesses.asCString());
586542
MA->setNewAccessRelation(isl::manage(NewAccessMap));
587543
} else {
588544
isl_map_free(NewAccessMap);
@@ -597,7 +553,7 @@ bool JSONImporter::importAccesses(Scop &S, Json::Value &JScop,
597553
}
598554

599555
/// Check whether @p SAI and @p Array represent the same array.
600-
bool areArraysEqual(ScopArrayInfo *SAI, Json::Value Array) {
556+
static bool areArraysEqual(ScopArrayInfo *SAI, Json::Value Array) {
601557
std::string Buffer;
602558
llvm::raw_string_ostream RawStringOstream(Buffer);
603559

@@ -648,8 +604,8 @@ bool areArraysEqual(ScopArrayInfo *SAI, Json::Value Array) {
648604
/// @param TypeTextRepresentation The textual representation of the type.
649605
/// @return The pointer to the primitive type, if this type is accepted
650606
/// or nullptr otherwise.
651-
Type *parseTextType(const std::string &TypeTextRepresentation,
652-
LLVMContext &LLVMContext) {
607+
static Type *parseTextType(const std::string &TypeTextRepresentation,
608+
LLVMContext &LLVMContext) {
653609
std::map<std::string, Type *> MapStrToType = {
654610
{"void", Type::getVoidTy(LLVMContext)},
655611
{"half", Type::getHalfTy(LLVMContext)},
@@ -674,7 +630,13 @@ Type *parseTextType(const std::string &TypeTextRepresentation,
674630
return nullptr;
675631
}
676632

677-
bool JSONImporter::importArrays(Scop &S, Json::Value &JScop) {
633+
/// Import new arrays from JScop.
634+
///
635+
/// @param S The scop to update.
636+
/// @param JScop The JScop file describing new arrays.
637+
///
638+
/// @returns True if the import succeeded, otherwise False.
639+
static bool importArrays(Scop &S, Json::Value &JScop) {
678640
Json::Value Arrays = JScop["arrays"];
679641
if (Arrays.size() == 0)
680642
return true;
@@ -726,12 +688,18 @@ bool JSONImporter::importArrays(Scop &S, Json::Value &JScop) {
726688
return true;
727689
}
728690

729-
bool JSONImporter::runOnScop(Scop &S) {
730-
const Dependences &D =
731-
getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
732-
const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
733-
734-
std::string FileName = ImportDir + "/" + getFileName(S);
691+
/// Import a Scop from a JSCOP file
692+
/// @param S The scop to be modified
693+
/// @param D Dependence Info
694+
/// @param DL The DataLayout of the function
695+
/// @param NewAccessStrings Optionally record the imported access strings
696+
///
697+
/// @returns true on success, false otherwise. Beware that if this returns
698+
/// false, the Scop may still have been modified. In this case the Scop contains
699+
/// invalid information.
700+
static bool importScop(Scop &S, const Dependences &D, const DataLayout &DL,
701+
std::vector<std::string> *NewAccessStrings = nullptr) {
702+
std::string FileName = ImportDir + "/" + getFileName(S, ImportPostfix);
735703

736704
std::string FunctionName = S.getFunction().getName();
737705
errs() << "Reading JScop '" << S.getNameStr() << "' in function '"
@@ -770,11 +738,50 @@ bool JSONImporter::runOnScop(Scop &S) {
770738
if (!Success)
771739
return false;
772740

773-
Success = importAccesses(S, jscop, DL);
741+
Success = importAccesses(S, jscop, DL, NewAccessStrings);
774742

775743
if (!Success)
776744
return false;
745+
return true;
746+
}
747+
748+
char JSONExporter::ID = 0;
749+
void JSONExporter::printScop(raw_ostream &OS, Scop &S) const { OS << S; }
750+
751+
bool JSONExporter::runOnScop(Scop &S) {
752+
exportScop(S);
753+
return false;
754+
}
755+
756+
void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const {
757+
AU.setPreservesAll();
758+
AU.addRequired<ScopInfoRegionPass>();
759+
}
760+
761+
Pass *polly::createJSONExporterPass() { return new JSONExporter(); }
777762

763+
PreservedAnalyses JSONExportPass::run(Scop &S, ScopAnalysisManager &SAM,
764+
ScopStandardAnalysisResults &SAR,
765+
SPMUpdater &) {
766+
exportScop(S);
767+
return PreservedAnalyses::all();
768+
}
769+
770+
char JSONImporter::ID = 0;
771+
772+
void JSONImporter::printScop(raw_ostream &OS, Scop &S) const {
773+
OS << S;
774+
for (std::vector<std::string>::const_iterator I = NewAccessStrings.begin(),
775+
E = NewAccessStrings.end();
776+
I != E; I++)
777+
OS << "New access function '" << *I << "' detected in JSCOP file\n";
778+
}
779+
780+
bool JSONImporter::runOnScop(Scop &S) {
781+
const Dependences &D =
782+
getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
783+
const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
784+
importScop(S, D, DL, &NewAccessStrings);
778785
return false;
779786
}
780787

@@ -785,6 +792,24 @@ void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const {
785792

786793
Pass *polly::createJSONImporterPass() { return new JSONImporter(); }
787794

795+
PreservedAnalyses JSONImportPass::run(Scop &S, ScopAnalysisManager &SAM,
796+
ScopStandardAnalysisResults &SAR,
797+
SPMUpdater &) {
798+
const Dependences &D =
799+
SAM.getResult<DependenceAnalysis>(S, SAR).getDependences(
800+
Dependences::AL_Statement);
801+
const DataLayout &DL = S.getFunction().getParent()->getDataLayout();
802+
803+
importScop(S, D, DL);
804+
805+
// This invalidates all analyses on Scop.
806+
PreservedAnalyses PA;
807+
PA.preserveSet<AllAnalysesOn<Module>>();
808+
PA.preserveSet<AllAnalysesOn<Function>>();
809+
PA.preserveSet<AllAnalysesOn<Loop>>();
810+
return PA;
811+
}
812+
788813
INITIALIZE_PASS_BEGIN(JSONExporter, "polly-export-jscop",
789814
"Polly - Export Scops as JSON"
790815
" (Writes a .jscop file for each Scop)",

‎polly/lib/Support/PollyPasses.def

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ SCOP_ANALYSIS("polly-dependences", DependenceAnalysis())
2323
#ifndef SCOP_PASS
2424
#define SCOP_PASS(NAME, CREATE_PASS)
2525
#endif
26+
SCOP_PASS("polly-export-jscop", JSONExportPass())
27+
SCOP_PASS("polly-import-jscop", JSONImportPass())
2628
SCOP_PASS("print<polly-ast>", IslAstPrinterPass(outs()))
2729
SCOP_PASS("print<polly-dependences>", DependenceInfoPrinterPass(outs()))
2830
SCOP_PASS("polly-codegen", CodeGenerationPass())

‎polly/lib/Support/RegisterPasses.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "polly/DependenceInfo.h"
3131
#include "polly/FlattenSchedule.h"
3232
#include "polly/ForwardOpTree.h"
33+
#include "polly/JSONExporter.h"
3334
#include "polly/LinkAllPasses.h"
3435
#include "polly/Options.h"
3536
#include "polly/PolyhedralInfo.h"
@@ -473,7 +474,8 @@ static void buildDefaultPollyPipeline(FunctionPassManager &PM,
473474
assert(!EnablePolyhedralInfo && "This option is not implemented");
474475
assert(!EnableDeLICM && "This option is not implemented");
475476
assert(!EnableSimplify && "This option is not implemented");
476-
assert(!ImportJScop && "This option is not implemented");
477+
if (ImportJScop)
478+
SPM.addPass(JSONImportPass());
477479
assert(!DeadCodeElim && "This option is not implemented");
478480
assert(!EnablePruneUnprofitable && "This option is not implemented");
479481
if (Target == TARGET_CPU || Target == TARGET_HYBRID)

0 commit comments

Comments
 (0)
Please sign in to comment.