diff --git a/polly/lib/Exchange/JSONExporter.cpp b/polly/lib/Exchange/JSONExporter.cpp index bc680fbc9a81ae460fe12e126ee3ea0b4741c13b..73177ce757d2415a6a16cb1d29e818f949783fef 100644 --- a/polly/lib/Exchange/JSONExporter.cpp +++ b/polly/lib/Exchange/JSONExporter.cpp @@ -73,7 +73,7 @@ struct JSONExporter : public ScopPass { struct JSONImporter : public ScopPass { static char ID; - std::vector newAccessStrings; + std::vector NewAccessStrings; explicit JSONImporter() : ScopPass(ID) {} /// Import a new context from JScop. @@ -96,6 +96,15 @@ struct JSONImporter : public ScopPass { /// @returns True if the import succeeded, otherwise False. bool importSchedule(Scop &S, Json::Value &JScop, const Dependences &D); + /// Import new memory accesses from JScop. + /// + /// @param S The scop to update. + /// @param JScop The JScop file describing the new schedule. + /// @param DL The datalayout 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; /// @brief Import new access functions for SCoP @p S from a JSON file. @@ -209,8 +218,8 @@ std::string JSONImporter::getFileName(Scop &S) const { void JSONImporter::printScop(raw_ostream &OS, Scop &S) const { S.print(OS); - for (std::vector::const_iterator I = newAccessStrings.begin(), - E = newAccessStrings.end(); + for (std::vector::const_iterator I = NewAccessStrings.begin(), + E = NewAccessStrings.end(); I != E; I++) OS << "New access function '" << *I << "'detected in JSCOP file\n"; } @@ -276,65 +285,28 @@ bool JSONImporter::importSchedule(Scop &S, Json::Value &JScop, return true; } -bool JSONImporter::runOnScop(Scop &S) { - const Dependences &D = - getAnalysis().getDependences(Dependences::AL_Statement); - const DataLayout &DL = S.getFunction().getParent()->getDataLayout(); - - std::string FileName = ImportDir + "/" + getFileName(S); - - std::string FunctionName = S.getFunction().getName(); - errs() << "Reading JScop '" << S.getNameStr() << "' in function '" - << FunctionName << "' from '" << FileName << "'.\n"; - ErrorOr> result = - MemoryBuffer::getFile(FileName); - std::error_code ec = result.getError(); - - if (ec) { - errs() << "File could not be read: " << ec.message() << "\n"; - return false; - } - - Json::Reader reader; - Json::Value jscop; - - bool parsingSuccessful = reader.parse(result.get()->getBufferStart(), jscop); - - if (!parsingSuccessful) { - errs() << "JSCoP file could not be parsed\n"; - return false; - } - - bool Success = importContext(S, jscop); - - if (!Success) - return false; - - Success = importSchedule(S, jscop, D); - - if (!Success) - return false; - - int statementIdx = 0; +bool JSONImporter::importAccesses(Scop &S, Json::Value &JScop, + const DataLayout &DL) { + int StatementIdx = 0; for (ScopStmt &Stmt : S) { - int memoryAccessIdx = 0; + int MemoryAccessIdx = 0; for (MemoryAccess *MA : Stmt) { - Json::Value accesses = jscop["statements"][statementIdx]["accesses"] - [memoryAccessIdx]["relation"]; - isl_map *newAccessMap = - isl_map_read_from_str(S.getIslCtx(), accesses.asCString()); - isl_map *currentAccessMap = MA->getAccessRelation(); - - if (isl_map_dim(newAccessMap, isl_dim_param) != - isl_map_dim(currentAccessMap, isl_dim_param)) { + Json::Value Accesses = JScop["statements"][StatementIdx]["accesses"] + [MemoryAccessIdx]["relation"]; + isl_map *NewAccessMap = + isl_map_read_from_str(S.getIslCtx(), Accesses.asCString()); + isl_map *CurrentAccessMap = MA->getAccessRelation(); + + if (isl_map_dim(NewAccessMap, isl_dim_param) != + isl_map_dim(CurrentAccessMap, isl_dim_param)) { errs() << "JScop file changes the number of parameter dimensions\n"; - isl_map_free(currentAccessMap); - isl_map_free(newAccessMap); + isl_map_free(CurrentAccessMap); + isl_map_free(NewAccessMap); return false; } - isl_id *OutId = isl_map_get_tuple_id(currentAccessMap, isl_dim_out); - newAccessMap = isl_map_set_tuple_id(newAccessMap, isl_dim_out, OutId); + isl_id *OutId = isl_map_get_tuple_id(CurrentAccessMap, isl_dim_out); + NewAccessMap = isl_map_set_tuple_id(NewAccessMap, isl_dim_out, OutId); if (MA->isArrayKind()) { // We keep the old alignment, thus we cannot allow accesses to memory @@ -352,17 +324,17 @@ bool JSONImporter::runOnScop(Scop &S) { } if (SpecialAlignment) { - isl_set *newAccessSet = isl_map_range(isl_map_copy(newAccessMap)); - isl_set *currentAccessSet = - isl_map_range(isl_map_copy(currentAccessMap)); - bool isSubset = isl_set_is_subset(newAccessSet, currentAccessSet); - isl_set_free(newAccessSet); - isl_set_free(currentAccessSet); - - if (!isSubset) { + isl_set *NewAccessSet = isl_map_range(isl_map_copy(NewAccessMap)); + isl_set *CurrentAccessSet = + isl_map_range(isl_map_copy(CurrentAccessMap)); + bool IsSubset = isl_set_is_subset(NewAccessSet, CurrentAccessSet); + isl_set_free(NewAccessSet); + isl_set_free(CurrentAccessSet); + + if (!IsSubset) { errs() << "JScop file changes the accessed memory\n"; - isl_map_free(currentAccessMap); - isl_map_free(newAccessMap); + isl_map_free(CurrentAccessMap); + isl_map_free(NewAccessMap); return false; } } @@ -371,27 +343,27 @@ bool JSONImporter::runOnScop(Scop &S) { // We need to copy the isl_ids for the parameter dimensions to the new // map. Without doing this the current map would have different // ids then the new one, even though both are named identically. - for (unsigned i = 0; i < isl_map_dim(currentAccessMap, isl_dim_param); + for (unsigned i = 0; i < isl_map_dim(CurrentAccessMap, isl_dim_param); i++) { - isl_id *id = isl_map_get_dim_id(currentAccessMap, isl_dim_param, i); - newAccessMap = isl_map_set_dim_id(newAccessMap, isl_dim_param, i, id); + isl_id *Id = isl_map_get_dim_id(CurrentAccessMap, isl_dim_param, i); + NewAccessMap = isl_map_set_dim_id(NewAccessMap, isl_dim_param, i, Id); } // Copy the old tuple id. This is necessary to retain the user pointer, // that stores the reference to the ScopStmt this access belongs to. - isl_id *Id = isl_map_get_tuple_id(currentAccessMap, isl_dim_in); - newAccessMap = isl_map_set_tuple_id(newAccessMap, isl_dim_in, Id); + isl_id *Id = isl_map_get_tuple_id(CurrentAccessMap, isl_dim_in); + NewAccessMap = isl_map_set_tuple_id(NewAccessMap, isl_dim_in, Id); - if (!isl_map_has_equal_space(currentAccessMap, newAccessMap)) { + if (!isl_map_has_equal_space(CurrentAccessMap, NewAccessMap)) { errs() << "JScop file contains access function with incompatible " << "dimensions\n"; - isl_map_free(currentAccessMap); - isl_map_free(newAccessMap); + isl_map_free(CurrentAccessMap); + isl_map_free(NewAccessMap); return false; } - auto NewAccessDomain = isl_map_domain(isl_map_copy(newAccessMap)); - auto CurrentAccessDomain = isl_map_domain(isl_map_copy(currentAccessMap)); + auto NewAccessDomain = isl_map_domain(isl_map_copy(NewAccessMap)); + auto CurrentAccessDomain = isl_map_domain(isl_map_copy(CurrentAccessMap)); NewAccessDomain = isl_set_intersect_params(NewAccessDomain, S.getContext()); @@ -403,28 +375,75 @@ bool JSONImporter::runOnScop(Scop &S) { errs() << "Mapping not defined for all iteration domain elements\n"; isl_set_free(CurrentAccessDomain); isl_set_free(NewAccessDomain); - isl_map_free(currentAccessMap); - isl_map_free(newAccessMap); + isl_map_free(CurrentAccessMap); + isl_map_free(NewAccessMap); return false; } isl_set_free(CurrentAccessDomain); isl_set_free(NewAccessDomain); - if (!isl_map_is_equal(newAccessMap, currentAccessMap)) { + if (!isl_map_is_equal(NewAccessMap, CurrentAccessMap)) { // Statistics. ++NewAccessMapFound; - newAccessStrings.push_back(accesses.asCString()); - MA->setNewAccessRelation(newAccessMap); + NewAccessStrings.push_back(Accesses.asCString()); + MA->setNewAccessRelation(NewAccessMap); } else { - isl_map_free(newAccessMap); + isl_map_free(NewAccessMap); } - isl_map_free(currentAccessMap); - memoryAccessIdx++; + isl_map_free(CurrentAccessMap); + MemoryAccessIdx++; } - statementIdx++; + StatementIdx++; } + return true; +} + +bool JSONImporter::runOnScop(Scop &S) { + const Dependences &D = + getAnalysis().getDependences(Dependences::AL_Statement); + const DataLayout &DL = S.getFunction().getParent()->getDataLayout(); + + std::string FileName = ImportDir + "/" + getFileName(S); + + std::string FunctionName = S.getFunction().getName(); + errs() << "Reading JScop '" << S.getNameStr() << "' in function '" + << FunctionName << "' from '" << FileName << "'.\n"; + ErrorOr> result = + MemoryBuffer::getFile(FileName); + std::error_code ec = result.getError(); + + if (ec) { + errs() << "File could not be read: " << ec.message() << "\n"; + return false; + } + + Json::Reader reader; + Json::Value jscop; + + bool parsingSuccessful = reader.parse(result.get()->getBufferStart(), jscop); + + if (!parsingSuccessful) { + errs() << "JSCoP file could not be parsed\n"; + return false; + } + + bool Success = importContext(S, jscop); + + if (!Success) + return false; + + Success = importSchedule(S, jscop, D); + + if (!Success) + return false; + + Success = importAccesses(S, jscop, DL); + + if (!Success) + return false; + return false; }