1 //===-- JSONExporter.cpp - Export Scops as JSON -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Export the Scops build by ScopInfo pass as a JSON file.
12 //===----------------------------------------------------------------------===//
14 #include "polly/DependenceInfo.h"
15 #include "polly/LinkAllPasses.h"
16 #include "polly/Options.h"
17 #include "polly/ScopInfo.h"
18 #include "polly/ScopPass.h"
19 #include "polly/Support/ScopLocation.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/Analysis/RegionInfo.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/MemoryBuffer.h"
25 #include "llvm/Support/ToolOutputFile.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "isl/constraint.h"
29 #include "isl/printer.h"
31 #include "isl/union_map.h"
32 #include "json/reader.h"
33 #include "json/writer.h"
36 #include <system_error>
39 using namespace polly
;
41 #define DEBUG_TYPE "polly-import-jscop"
43 STATISTIC(NewAccessMapFound
, "Number of updated access functions");
46 static cl::opt
<std::string
>
47 ImportDir("polly-import-jscop-dir",
48 cl::desc("The directory to import the .jscop files from."),
49 cl::Hidden
, cl::value_desc("Directory path"), cl::ValueRequired
,
50 cl::init("."), cl::cat(PollyCategory
));
52 static cl::opt
<std::string
>
53 ImportPostfix("polly-import-jscop-postfix",
54 cl::desc("Postfix to append to the import .jsop files."),
55 cl::Hidden
, cl::value_desc("File postfix"), cl::ValueRequired
,
56 cl::init(""), cl::cat(PollyCategory
));
58 struct JSONExporter
: public ScopPass
{
60 explicit JSONExporter() : ScopPass(ID
) {}
62 std::string
getFileName(Scop
&S
) const;
63 Json::Value
getJSON(Scop
&S
) const;
65 /// Export the SCoP @p S to a JSON file.
66 bool runOnScop(Scop
&S
) override
;
68 /// Print the SCoP @p S as it is exported.
69 void printScop(raw_ostream
&OS
, Scop
&S
) const override
;
71 /// Register all analyses and transformation required.
72 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
75 struct JSONImporter
: public ScopPass
{
77 std::vector
<std::string
> NewAccessStrings
;
78 explicit JSONImporter() : ScopPass(ID
) {}
80 /// Import a new context from JScop.
82 /// @param S The scop to update.
83 /// @param JScop The JScop file describing the new schedule.
85 /// @returns True if the import succeeded, otherwise False.
86 bool importContext(Scop
&S
, Json::Value
&JScop
);
88 /// Import a new schedule from JScop.
90 /// ... and verify that the new schedule does preserve existing data
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.
97 /// @returns True if the import succeeded, otherwise False.
98 bool importSchedule(Scop
&S
, Json::Value
&JScop
, const Dependences
&D
);
100 /// Import new arrays from JScop.
102 /// @param S The scop to update.
103 /// @param JScop The JScop file describing new arrays.
105 /// @returns True if the import succeeded, otherwise False.
106 bool importArrays(Scop
&S
, Json::Value
&JScop
);
108 /// Import new memory accesses from JScop.
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.
114 /// @returns True if the import succeeded, otherwise False.
115 bool importAccesses(Scop
&S
, Json::Value
&JScop
, const DataLayout
&DL
);
117 std::string
getFileName(Scop
&S
) const;
119 /// Import new access functions for SCoP @p S from a JSON file.
120 bool runOnScop(Scop
&S
) override
;
122 /// Print the SCoP @p S and the imported access functions.
123 void printScop(raw_ostream
&OS
, Scop
&S
) const override
;
125 /// Register all analyses and transformation required.
126 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
130 char JSONExporter::ID
= 0;
131 std::string
JSONExporter::getFileName(Scop
&S
) const {
132 std::string FunctionName
= S
.getFunction().getName();
133 std::string FileName
= FunctionName
+ "___" + S
.getNameStr() + ".jscop";
137 void JSONExporter::printScop(raw_ostream
&OS
, Scop
&S
) const { OS
<< S
; }
139 /// Export all arrays from the Scop.
141 /// @param S The Scop containing the arrays.
143 /// @returns Json::Value containing the arrays.
144 Json::Value
exportArrays(const Scop
&S
) {
147 llvm::raw_string_ostream
RawStringOstream(Buffer
);
149 for (auto &SAI
: S
.arrays()) {
150 if (!SAI
->isArrayKind())
154 Array
["name"] = SAI
->getName();
156 if (!SAI
->getDimensionSize(i
)) {
157 Array
["sizes"].append("*");
160 for (; i
< SAI
->getNumberOfDimensions(); i
++) {
161 SAI
->getDimensionSize(i
)->print(RawStringOstream
);
162 Array
["sizes"].append(RawStringOstream
.str());
165 SAI
->getElementType()->print(RawStringOstream
);
166 Array
["type"] = RawStringOstream
.str();
168 Arrays
.append(Array
);
173 Json::Value
JSONExporter::getJSON(Scop
&S
) const {
175 unsigned LineBegin
, LineEnd
;
176 std::string FileName
;
178 getDebugLocation(&S
.getRegion(), LineBegin
, LineEnd
, FileName
);
179 std::string Location
;
180 if (LineBegin
!= (unsigned)-1)
181 Location
= FileName
+ ":" + std::to_string(LineBegin
) + "-" +
182 std::to_string(LineEnd
);
184 root
["name"] = S
.getNameStr();
185 root
["context"] = S
.getContextStr();
186 if (LineBegin
!= (unsigned)-1)
187 root
["location"] = Location
;
189 root
["arrays"] = exportArrays(S
);
193 for (ScopStmt
&Stmt
: S
) {
194 Json::Value statement
;
196 statement
["name"] = Stmt
.getBaseName();
197 statement
["domain"] = Stmt
.getDomainStr();
198 statement
["schedule"] = Stmt
.getScheduleStr();
199 statement
["accesses"];
201 for (MemoryAccess
*MA
: Stmt
) {
204 access
["kind"] = MA
->isRead() ? "read" : "write";
205 access
["relation"] = MA
->getAccessRelationStr();
207 statement
["accesses"].append(access
);
210 root
["statements"].append(statement
);
216 bool JSONExporter::runOnScop(Scop
&S
) {
217 std::string FileName
= ImportDir
+ "/" + getFileName(S
);
219 Json::Value jscop
= getJSON(S
);
220 Json::StyledWriter writer
;
221 std::string fileContent
= writer
.write(jscop
);
225 tool_output_file
F(FileName
, EC
, llvm::sys::fs::F_Text
);
227 std::string FunctionName
= S
.getFunction().getName();
228 errs() << "Writing JScop '" << S
.getNameStr() << "' in function '"
229 << FunctionName
<< "' to '" << FileName
<< "'.\n";
232 F
.os() << fileContent
;
234 if (!F
.os().has_error()) {
241 errs() << " error opening file for writing!\n";
242 F
.os().clear_error();
247 void JSONExporter::getAnalysisUsage(AnalysisUsage
&AU
) const {
248 AU
.setPreservesAll();
249 AU
.addRequired
<ScopInfoRegionPass
>();
252 Pass
*polly::createJSONExporterPass() { return new JSONExporter(); }
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";
259 if (ImportPostfix
!= "")
260 FileName
+= "." + ImportPostfix
;
265 void JSONImporter::printScop(raw_ostream
&OS
, Scop
&S
) const {
267 for (std::vector
<std::string
>::const_iterator I
= NewAccessStrings
.begin(),
268 E
= NewAccessStrings
.end();
270 OS
<< "New access function '" << *I
<< "' detected in JSCOP file\n";
273 typedef Dependences::StatementToIslMapTy StatementToIslMapTy
;
275 bool JSONImporter::importContext(Scop
&S
, Json::Value
&JScop
) {
276 isl_set
*OldContext
= S
.getContext();
278 // Check if key 'context' is present.
279 if (!JScop
.isMember("context")) {
280 errs() << "JScop file has no key named 'context'.\n";
281 isl_set_free(OldContext
);
285 isl_set
*NewContext
=
286 isl_set_read_from_str(S
.getIslCtx(), JScop
["context"].asCString());
288 // Check whether the context was parsed successfully.
290 errs() << "The context was not parsed successfully by ISL.\n";
291 isl_set_free(NewContext
);
292 isl_set_free(OldContext
);
296 // Check if the isl_set is a parameter set.
297 if (!isl_set_is_params(NewContext
)) {
298 errs() << "The isl_set is not a parameter set.\n";
299 isl_set_free(NewContext
);
300 isl_set_free(OldContext
);
304 unsigned OldContextDim
= isl_set_dim(OldContext
, isl_dim_param
);
305 unsigned NewContextDim
= isl_set_dim(NewContext
, isl_dim_param
);
307 // Check if the imported context has the right number of parameters.
308 if (OldContextDim
!= NewContextDim
) {
309 errs() << "Imported context has the wrong number of parameters : "
310 << "Found " << NewContextDim
<< " Expected " << OldContextDim
312 isl_set_free(NewContext
);
313 isl_set_free(OldContext
);
317 for (unsigned i
= 0; i
< OldContextDim
; i
++) {
318 isl_id
*Id
= isl_set_get_dim_id(OldContext
, isl_dim_param
, i
);
319 NewContext
= isl_set_set_dim_id(NewContext
, isl_dim_param
, i
, Id
);
322 isl_set_free(OldContext
);
323 S
.setContext(NewContext
);
327 bool JSONImporter::importSchedule(Scop
&S
, Json::Value
&JScop
,
328 const Dependences
&D
) {
329 StatementToIslMapTy NewSchedule
;
331 // Check if key 'statements' is present.
332 if (!JScop
.isMember("statements")) {
333 errs() << "JScop file has no key name 'statements'.\n";
337 Json::Value statements
= JScop
["statements"];
339 // Check whether the number of indices equals the number of statements
340 if (statements
.size() != S
.getSize()) {
341 errs() << "The number of indices and the number of statements differ.\n";
346 for (ScopStmt
&Stmt
: S
) {
347 // Check if key 'schedule' is present.
348 if (!statements
[Index
].isMember("schedule")) {
349 errs() << "Statement " << Index
<< " has no 'schedule' key.\n";
350 for (auto Element
: NewSchedule
) {
351 isl_map_free(Element
.second
);
355 Json::Value Schedule
= statements
[Index
]["schedule"];
356 assert(!Schedule
.asString().empty() &&
357 "Schedules that contain extension nodes require special handling.");
358 isl_map
*Map
= isl_map_read_from_str(S
.getIslCtx(), Schedule
.asCString());
360 // Check whether the schedule was parsed successfully
362 errs() << "The schedule was not parsed successfully (index = " << Index
364 for (auto Element
: NewSchedule
) {
365 isl_map_free(Element
.second
);
370 isl_space
*Space
= Stmt
.getDomainSpace();
372 // Copy the old tuple id. This is necessary to retain the user pointer,
373 // that stores the reference to the ScopStmt this schedule belongs to.
374 Map
= isl_map_set_tuple_id(Map
, isl_dim_in
,
375 isl_space_get_tuple_id(Space
, isl_dim_set
));
376 for (unsigned i
= 0; i
< isl_space_dim(Space
, isl_dim_param
); i
++) {
377 isl_id
*Id
= isl_space_get_dim_id(Space
, isl_dim_param
, i
);
378 Map
= isl_map_set_dim_id(Map
, isl_dim_param
, i
, Id
);
380 isl_space_free(Space
);
381 NewSchedule
[&Stmt
] = Map
;
385 // Check whether the new schedule is valid or not.
386 if (!D
.isValidSchedule(S
, &NewSchedule
)) {
387 errs() << "JScop file contains a schedule that changes the "
388 << "dependences. Use -disable-polly-legality to continue anyways\n";
389 for (auto Element
: NewSchedule
)
390 isl_map_free(Element
.second
);
394 auto ScheduleMap
= isl_union_map_empty(S
.getParamSpace());
395 for (ScopStmt
&Stmt
: S
) {
396 if (NewSchedule
.find(&Stmt
) != NewSchedule
.end())
397 ScheduleMap
= isl_union_map_add_map(ScheduleMap
, NewSchedule
[&Stmt
]);
399 ScheduleMap
= isl_union_map_add_map(ScheduleMap
, Stmt
.getSchedule());
402 S
.setSchedule(ScheduleMap
);
407 bool JSONImporter::importAccesses(Scop
&S
, Json::Value
&JScop
,
408 const DataLayout
&DL
) {
409 int StatementIdx
= 0;
411 // Check if key 'statements' is present.
412 if (!JScop
.isMember("statements")) {
413 errs() << "JScop file has no key name 'statements'.\n";
416 Json::Value statements
= JScop
["statements"];
418 // Check whether the number of indices equals the number of statements
419 if (statements
.size() != S
.getSize()) {
420 errs() << "The number of indices and the number of statements differ.\n";
424 for (ScopStmt
&Stmt
: S
) {
425 int MemoryAccessIdx
= 0;
427 // Check if key 'accesses' is present.
428 if (!statements
[StatementIdx
].isMember("accesses")) {
430 << "Statement from JScop file has no key name 'accesses' for index "
431 << StatementIdx
<< ".\n";
435 // Check whether the number of indices equals the number of memory accesses
436 if (Stmt
.size() != statements
[StatementIdx
]["accesses"].size()) {
437 errs() << "The number of memory accesses in the JSop file and the number "
438 "of memory accesses differ for index "
439 << StatementIdx
<< ".\n";
443 for (MemoryAccess
*MA
: Stmt
) {
444 // Check if key 'relation' is present.
445 Json::Value JsonMemoryAccess
=
446 statements
[StatementIdx
]["accesses"][MemoryAccessIdx
];
447 if (!JsonMemoryAccess
.isMember("relation")) {
448 errs() << "Memory access number " << MemoryAccessIdx
449 << " has no key name 'relation' for statement number "
450 << StatementIdx
<< ".\n";
453 Json::Value Accesses
= JsonMemoryAccess
["relation"];
454 isl_map
*NewAccessMap
=
455 isl_map_read_from_str(S
.getIslCtx(), Accesses
.asCString());
457 // Check whether the access was parsed successfully
459 errs() << "The access was not parsed successfully by ISL.\n";
462 isl_map
*CurrentAccessMap
= MA
->getAccessRelation().release();
464 // Check if the number of parameter change
465 if (isl_map_dim(NewAccessMap
, isl_dim_param
) !=
466 isl_map_dim(CurrentAccessMap
, isl_dim_param
)) {
467 errs() << "JScop file changes the number of parameter dimensions.\n";
468 isl_map_free(CurrentAccessMap
);
469 isl_map_free(NewAccessMap
);
475 // If the NewAccessMap has zero dimensions, it is the scalar access; it
476 // must be the same as before.
477 // If it has at least one dimension, it's an array access; search for its
479 if (isl_map_dim(NewAccessMap
, isl_dim_out
) >= 1) {
480 NewOutId
= isl_map_get_tuple_id(NewAccessMap
, isl_dim_out
);
481 auto *SAI
= S
.getArrayInfoByName(isl_id_get_name(NewOutId
));
482 isl_id
*OutId
= isl_map_get_tuple_id(CurrentAccessMap
, isl_dim_out
);
483 auto *OutSAI
= ScopArrayInfo::getFromId(isl::manage(OutId
));
484 if (!SAI
|| SAI
->getElementType() != OutSAI
->getElementType()) {
485 errs() << "JScop file contains access function with undeclared "
487 isl_map_free(CurrentAccessMap
);
488 isl_map_free(NewAccessMap
);
489 isl_id_free(NewOutId
);
492 isl_id_free(NewOutId
);
493 NewOutId
= SAI
->getBasePtrId().release();
495 NewOutId
= isl_map_get_tuple_id(CurrentAccessMap
, isl_dim_out
);
498 NewAccessMap
= isl_map_set_tuple_id(NewAccessMap
, isl_dim_out
, NewOutId
);
500 if (MA
->isArrayKind()) {
501 // We keep the old alignment, thus we cannot allow accesses to memory
502 // locations that were not accessed before if the alignment of the
503 // access is not the default alignment.
504 bool SpecialAlignment
= true;
505 if (LoadInst
*LoadI
= dyn_cast
<LoadInst
>(MA
->getAccessInstruction())) {
507 LoadI
->getAlignment() &&
508 DL
.getABITypeAlignment(LoadI
->getType()) != LoadI
->getAlignment();
509 } else if (StoreInst
*StoreI
=
510 dyn_cast
<StoreInst
>(MA
->getAccessInstruction())) {
512 StoreI
->getAlignment() &&
513 DL
.getABITypeAlignment(StoreI
->getValueOperand()->getType()) !=
514 StoreI
->getAlignment();
517 if (SpecialAlignment
) {
518 isl_set
*NewAccessSet
= isl_map_range(isl_map_copy(NewAccessMap
));
519 isl_set
*CurrentAccessSet
=
520 isl_map_range(isl_map_copy(CurrentAccessMap
));
521 bool IsSubset
= isl_set_is_subset(NewAccessSet
, CurrentAccessSet
);
522 isl_set_free(NewAccessSet
);
523 isl_set_free(CurrentAccessSet
);
525 // Check if the JScop file changes the accessed memory.
527 errs() << "JScop file changes the accessed memory\n";
528 isl_map_free(CurrentAccessMap
);
529 isl_map_free(NewAccessMap
);
535 // We need to copy the isl_ids for the parameter dimensions to the new
536 // map. Without doing this the current map would have different
537 // ids then the new one, even though both are named identically.
538 for (unsigned i
= 0; i
< isl_map_dim(CurrentAccessMap
, isl_dim_param
);
540 isl_id
*Id
= isl_map_get_dim_id(CurrentAccessMap
, isl_dim_param
, i
);
541 NewAccessMap
= isl_map_set_dim_id(NewAccessMap
, isl_dim_param
, i
, Id
);
544 // Copy the old tuple id. This is necessary to retain the user pointer,
545 // that stores the reference to the ScopStmt this access belongs to.
546 isl_id
*Id
= isl_map_get_tuple_id(CurrentAccessMap
, isl_dim_in
);
547 NewAccessMap
= isl_map_set_tuple_id(NewAccessMap
, isl_dim_in
, Id
);
549 auto NewAccessDomain
= isl_map_domain(isl_map_copy(NewAccessMap
));
550 auto CurrentAccessDomain
= isl_map_domain(isl_map_copy(CurrentAccessMap
));
552 if (!isl_set_has_equal_space(NewAccessDomain
, CurrentAccessDomain
)) {
553 errs() << "JScop file contains access function with incompatible "
555 isl_map_free(CurrentAccessMap
);
556 isl_map_free(NewAccessMap
);
557 isl_set_free(NewAccessDomain
);
558 isl_set_free(CurrentAccessDomain
);
563 isl_set_intersect_params(NewAccessDomain
, S
.getContext());
564 CurrentAccessDomain
=
565 isl_set_intersect_params(CurrentAccessDomain
, S
.getContext());
568 isl_set_is_subset(CurrentAccessDomain
, NewAccessDomain
) ==
570 errs() << "Mapping not defined for all iteration domain elements\n";
571 isl_set_free(CurrentAccessDomain
);
572 isl_set_free(NewAccessDomain
);
573 isl_map_free(CurrentAccessMap
);
574 isl_map_free(NewAccessMap
);
578 isl_set_free(CurrentAccessDomain
);
579 isl_set_free(NewAccessDomain
);
581 if (!isl_map_is_equal(NewAccessMap
, CurrentAccessMap
)) {
584 NewAccessStrings
.push_back(Accesses
.asCString());
585 MA
->setNewAccessRelation(NewAccessMap
);
587 isl_map_free(NewAccessMap
);
589 isl_map_free(CurrentAccessMap
);
598 /// Check whether @p SAI and @p Array represent the same array.
599 bool areArraysEqual(ScopArrayInfo
*SAI
, Json::Value Array
) {
601 llvm::raw_string_ostream
RawStringOstream(Buffer
);
603 // Check if key 'type' is present.
604 if (!Array
.isMember("type")) {
605 errs() << "Array has no key 'type'.\n";
609 // Check if key 'sizes' is present.
610 if (!Array
.isMember("sizes")) {
611 errs() << "Array has no key 'sizes'.\n";
615 // Check if key 'name' is present.
616 if (!Array
.isMember("name")) {
617 errs() << "Array has no key 'name'.\n";
621 if (SAI
->getName() != Array
["name"].asCString())
624 if (SAI
->getNumberOfDimensions() != Array
["sizes"].size())
627 for (unsigned i
= 1; i
< Array
["sizes"].size(); i
++) {
628 SAI
->getDimensionSize(i
)->print(RawStringOstream
);
629 if (RawStringOstream
.str() != Array
["sizes"][i
].asCString())
634 // Check if key 'type' differs from the current one or is not valid.
635 SAI
->getElementType()->print(RawStringOstream
);
636 if (RawStringOstream
.str() != Array
["type"].asCString()) {
637 errs() << "Array has not a valid type.\n";
644 /// Get the accepted primitive type from its textual representation
645 /// @p TypeTextRepresentation.
647 /// @param TypeTextRepresentation The textual representation of the type.
648 /// @return The pointer to the primitive type, if this type is accepted
649 /// or nullptr otherwise.
650 Type
*parseTextType(const std::string
&TypeTextRepresentation
,
651 LLVMContext
&LLVMContext
) {
652 std::map
<std::string
, Type
*> MapStrToType
= {
653 {"void", Type::getVoidTy(LLVMContext
)},
654 {"half", Type::getHalfTy(LLVMContext
)},
655 {"float", Type::getFloatTy(LLVMContext
)},
656 {"double", Type::getDoubleTy(LLVMContext
)},
657 {"x86_fp80", Type::getX86_FP80Ty(LLVMContext
)},
658 {"fp128", Type::getFP128Ty(LLVMContext
)},
659 {"ppc_fp128", Type::getPPC_FP128Ty(LLVMContext
)},
660 {"i1", Type::getInt1Ty(LLVMContext
)},
661 {"i8", Type::getInt8Ty(LLVMContext
)},
662 {"i16", Type::getInt16Ty(LLVMContext
)},
663 {"i32", Type::getInt32Ty(LLVMContext
)},
664 {"i64", Type::getInt64Ty(LLVMContext
)},
665 {"i128", Type::getInt128Ty(LLVMContext
)}};
667 auto It
= MapStrToType
.find(TypeTextRepresentation
);
668 if (It
!= MapStrToType
.end())
671 errs() << "Textual representation can not be parsed: "
672 << TypeTextRepresentation
<< "\n";
676 bool JSONImporter::importArrays(Scop
&S
, Json::Value
&JScop
) {
677 Json::Value Arrays
= JScop
["arrays"];
678 if (Arrays
.size() == 0)
681 unsigned ArrayIdx
= 0;
682 for (auto &SAI
: S
.arrays()) {
683 if (!SAI
->isArrayKind())
685 if (ArrayIdx
+ 1 > Arrays
.size()) {
686 errs() << "Not enough array entries in JScop file.\n";
689 if (!areArraysEqual(SAI
, Arrays
[ArrayIdx
])) {
690 errs() << "No match for array '" << SAI
->getName() << "' in JScop.\n";
696 for (; ArrayIdx
< Arrays
.size(); ArrayIdx
++) {
697 auto &Array
= Arrays
[ArrayIdx
];
699 parseTextType(Array
["type"].asCString(), S
.getSE()->getContext());
701 errs() << "Error while parsing element type for new array.\n";
704 std::vector
<unsigned> DimSizes
;
705 for (unsigned i
= 0; i
< Array
["sizes"].size(); i
++) {
706 auto Size
= std::stoi(Array
["sizes"][i
].asCString());
708 // Check if the size if positive.
710 errs() << "The size at index " << i
<< " is =< 0.\n";
714 DimSizes
.push_back(Size
);
718 S
.createScopArrayInfo(ElementType
, Array
["name"].asCString(), DimSizes
);
720 if (Array
.isMember("allocation")) {
721 NewSAI
->setIsOnHeap(Array
["allocation"].asString() == "heap");
728 bool JSONImporter::runOnScop(Scop
&S
) {
729 const Dependences
&D
=
730 getAnalysis
<DependenceInfo
>().getDependences(Dependences::AL_Statement
);
731 const DataLayout
&DL
= S
.getFunction().getParent()->getDataLayout();
733 std::string FileName
= ImportDir
+ "/" + getFileName(S
);
735 std::string FunctionName
= S
.getFunction().getName();
736 errs() << "Reading JScop '" << S
.getNameStr() << "' in function '"
737 << FunctionName
<< "' from '" << FileName
<< "'.\n";
738 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> result
=
739 MemoryBuffer::getFile(FileName
);
740 std::error_code ec
= result
.getError();
743 errs() << "File could not be read: " << ec
.message() << "\n";
750 bool parsingSuccessful
= reader
.parse(result
.get()->getBufferStart(), jscop
);
752 if (!parsingSuccessful
) {
753 errs() << "JSCoP file could not be parsed\n";
757 bool Success
= importContext(S
, jscop
);
762 Success
= importSchedule(S
, jscop
, D
);
767 Success
= importArrays(S
, jscop
);
772 Success
= importAccesses(S
, jscop
, DL
);
780 void JSONImporter::getAnalysisUsage(AnalysisUsage
&AU
) const {
781 ScopPass::getAnalysisUsage(AU
);
782 AU
.addRequired
<DependenceInfo
>();
785 Pass
*polly::createJSONImporterPass() { return new JSONImporter(); }
787 INITIALIZE_PASS_BEGIN(JSONExporter
, "polly-export-jscop",
788 "Polly - Export Scops as JSON"
789 " (Writes a .jscop file for each Scop)",
791 INITIALIZE_PASS_DEPENDENCY(DependenceInfo
)
792 INITIALIZE_PASS_END(JSONExporter
, "polly-export-jscop",
793 "Polly - Export Scops as JSON"
794 " (Writes a .jscop file for each Scop)",
797 INITIALIZE_PASS_BEGIN(JSONImporter
, "polly-import-jscop",
798 "Polly - Import Scops from JSON"
799 " (Reads a .jscop file for each Scop)",
801 INITIALIZE_PASS_DEPENDENCY(DependenceInfo
)
802 INITIALIZE_PASS_END(JSONImporter
, "polly-import-jscop",
803 "Polly - Import Scops from JSON"
804 " (Reads a .jscop file for each Scop)",