11
11
//
12
12
// ===----------------------------------------------------------------------===//
13
13
14
+ #include " polly/JSONExporter.h"
14
15
#include " polly/DependenceInfo.h"
15
16
#include " polly/LinkAllPasses.h"
16
17
#include " polly/Options.h"
@@ -59,9 +60,6 @@ struct JSONExporter : public ScopPass {
59
60
static char ID;
60
61
explicit JSONExporter () : ScopPass(ID) {}
61
62
62
- std::string getFileName (Scop &S) const ;
63
- Json::Value getJSON (Scop &S) const ;
64
-
65
63
// / Export the SCoP @p S to a JSON file.
66
64
bool runOnScop (Scop &S) override ;
67
65
@@ -76,46 +74,6 @@ struct JSONImporter : public ScopPass {
76
74
static char ID;
77
75
std::vector<std::string> NewAccessStrings;
78
76
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
-
119
77
// / Import new access functions for SCoP @p S from a JSON file.
120
78
bool runOnScop (Scop &S) override ;
121
79
@@ -127,21 +85,22 @@ struct JSONImporter : public ScopPass {
127
85
};
128
86
} // namespace
129
87
130
- char JSONExporter::ID = 0 ;
131
- std::string JSONExporter::getFileName (Scop &S) const {
88
+ static std::string getFileName (Scop &S, StringRef Suffix = " " ) {
132
89
std::string FunctionName = S.getFunction ().getName ();
133
90
std::string FileName = FunctionName + " ___" + S.getNameStr () + " .jscop" ;
91
+
92
+ if (Suffix != " " )
93
+ FileName += " ." + Suffix.str ();
94
+
134
95
return FileName;
135
96
}
136
97
137
- void JSONExporter::printScop (raw_ostream &OS, Scop &S) const { OS << S; }
138
-
139
98
// / Export all arrays from the Scop.
140
99
// /
141
100
// / @param S The Scop containing the arrays.
142
101
// /
143
102
// / @returns Json::Value containing the arrays.
144
- Json::Value exportArrays (const Scop &S) {
103
+ static Json::Value exportArrays (const Scop &S) {
145
104
Json::Value Arrays;
146
105
std::string Buffer;
147
106
llvm::raw_string_ostream RawStringOstream (Buffer);
@@ -170,7 +129,7 @@ Json::Value exportArrays(const Scop &S) {
170
129
return Arrays;
171
130
}
172
131
173
- Json::Value JSONExporter:: getJSON (Scop &S) const {
132
+ static Json::Value getJSON (Scop &S) {
174
133
Json::Value root;
175
134
unsigned LineBegin, LineEnd;
176
135
std::string FileName;
@@ -213,7 +172,7 @@ Json::Value JSONExporter::getJSON(Scop &S) const {
213
172
return root;
214
173
}
215
174
216
- bool JSONExporter::runOnScop (Scop &S) {
175
+ static void exportScop (Scop &S) {
217
176
std::string FileName = ImportDir + " /" + getFileName (S);
218
177
219
178
Json::Value jscop = getJSON (S);
@@ -234,45 +193,23 @@ bool JSONExporter::runOnScop(Scop &S) {
234
193
if (!F.os ().has_error ()) {
235
194
errs () << " \n " ;
236
195
F.keep ();
237
- return false ;
196
+ return ;
238
197
}
239
198
}
240
199
241
200
errs () << " error opening file for writing!\n " ;
242
201
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 " ;
271
202
}
272
203
273
204
typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
274
205
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) {
276
213
isl_set *OldContext = S.getContext ().release ();
277
214
278
215
// Check if key 'context' is present.
@@ -324,8 +261,17 @@ bool JSONImporter::importContext(Scop &S, Json::Value &JScop) {
324
261
return true ;
325
262
}
326
263
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) {
329
275
StatementToIslMapTy NewSchedule;
330
276
331
277
// Check if key 'statements' is present.
@@ -405,8 +351,17 @@ bool JSONImporter::importSchedule(Scop &S, Json::Value &JScop,
405
351
return true ;
406
352
}
407
353
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 ) {
410
365
int StatementIdx = 0 ;
411
366
412
367
// Check if key 'statements' is present.
@@ -582,7 +537,8 @@ bool JSONImporter::importAccesses(Scop &S, Json::Value &JScop,
582
537
if (!isl_map_is_equal (NewAccessMap, CurrentAccessMap)) {
583
538
// Statistics.
584
539
++NewAccessMapFound;
585
- NewAccessStrings.push_back (Accesses.asCString ());
540
+ if (NewAccessStrings)
541
+ NewAccessStrings->push_back (Accesses.asCString ());
586
542
MA->setNewAccessRelation (isl::manage (NewAccessMap));
587
543
} else {
588
544
isl_map_free (NewAccessMap);
@@ -597,7 +553,7 @@ bool JSONImporter::importAccesses(Scop &S, Json::Value &JScop,
597
553
}
598
554
599
555
// / 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) {
601
557
std::string Buffer;
602
558
llvm::raw_string_ostream RawStringOstream (Buffer);
603
559
@@ -648,8 +604,8 @@ bool areArraysEqual(ScopArrayInfo *SAI, Json::Value Array) {
648
604
// / @param TypeTextRepresentation The textual representation of the type.
649
605
// / @return The pointer to the primitive type, if this type is accepted
650
606
// / or nullptr otherwise.
651
- Type *parseTextType (const std::string &TypeTextRepresentation,
652
- LLVMContext &LLVMContext) {
607
+ static Type *parseTextType (const std::string &TypeTextRepresentation,
608
+ LLVMContext &LLVMContext) {
653
609
std::map<std::string, Type *> MapStrToType = {
654
610
{" void" , Type::getVoidTy (LLVMContext)},
655
611
{" half" , Type::getHalfTy (LLVMContext)},
@@ -674,7 +630,13 @@ Type *parseTextType(const std::string &TypeTextRepresentation,
674
630
return nullptr ;
675
631
}
676
632
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) {
678
640
Json::Value Arrays = JScop[" arrays" ];
679
641
if (Arrays.size () == 0 )
680
642
return true ;
@@ -726,12 +688,18 @@ bool JSONImporter::importArrays(Scop &S, Json::Value &JScop) {
726
688
return true ;
727
689
}
728
690
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);
735
703
736
704
std::string FunctionName = S.getFunction ().getName ();
737
705
errs () << " Reading JScop '" << S.getNameStr () << " ' in function '"
@@ -770,11 +738,50 @@ bool JSONImporter::runOnScop(Scop &S) {
770
738
if (!Success)
771
739
return false ;
772
740
773
- Success = importAccesses (S, jscop, DL);
741
+ Success = importAccesses (S, jscop, DL, NewAccessStrings );
774
742
775
743
if (!Success)
776
744
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 (); }
777
762
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);
778
785
return false ;
779
786
}
780
787
@@ -785,6 +792,24 @@ void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const {
785
792
786
793
Pass *polly::createJSONImporterPass () { return new JSONImporter (); }
787
794
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
+
788
813
INITIALIZE_PASS_BEGIN (JSONExporter, " polly-export-jscop" ,
789
814
" Polly - Export Scops as JSON"
790
815
" (Writes a .jscop file for each Scop)" ,
0 commit comments