[polly] r277263 - Extend the jscop interface to allow the user to declare new arrays and to reference these arrays from access expressions
Roman Gareev via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 30 02:25:52 PDT 2016
Author: romangareev
Date: Sat Jul 30 04:25:51 2016
New Revision: 277263
URL: http://llvm.org/viewvc/llvm-project?rev=277263&view=rev
Log:
Extend the jscop interface to allow the user to declare new arrays and to reference these arrays from access expressions
Extend the jscop interface to allow the user to export arrays. It is required
that already existing arrays of the list of arrays correspond to arrays
of the SCoP. Each array that is appended to the list will be newly created.
Furthermore, we allow the user to modify access expressions to reference
any array in case it has the same element type.
Reviewed-by: Tobias Grosser <tobias at grosser.es>
Differential Revision: https://reviews.llvm.org/D22828
Added:
polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays.ll
polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%bb9---%bb26.jscop
polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%bb9---%bb26.jscop.transformed
Modified:
polly/trunk/include/polly/CodeGen/IslNodeBuilder.h
polly/trunk/include/polly/ScopInfo.h
polly/trunk/lib/Analysis/ScopInfo.cpp
polly/trunk/lib/CodeGen/BlockGenerators.cpp
polly/trunk/lib/CodeGen/CodeGeneration.cpp
polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp
polly/trunk/lib/Exchange/JSONExporter.cpp
Modified: polly/trunk/include/polly/CodeGen/IslNodeBuilder.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/IslNodeBuilder.h?rev=277263&r1=277262&r2=277263&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/IslNodeBuilder.h (original)
+++ polly/trunk/include/polly/CodeGen/IslNodeBuilder.h Sat Jul 30 04:25:51 2016
@@ -55,6 +55,9 @@ public:
void addParameters(__isl_take isl_set *Context);
void create(__isl_take isl_ast_node *Node);
+ /// @brief Allocate memory for all new arrays created by Polly.
+ void allocateNewArrays();
+
/// @brief Preload all memory loads that are invariant.
bool preloadInvariantLoads();
Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=277263&r1=277262&r2=277263&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Sat Jul 30 04:25:51 2016
@@ -231,9 +231,10 @@ public:
/// @param Kind The kind of the array object.
/// @param DL The data layout of the module.
/// @param S The scop this array object belongs to.
+ /// @param BaseName The optional name of this memory reference.
ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *IslCtx,
ArrayRef<const SCEV *> DimensionSizes, enum MemoryKind Kind,
- const DataLayout &DL, Scop *S);
+ const DataLayout &DL, Scop *S, const char *BaseName = nullptr);
/// @brief Update the element type of the ScopArrayInfo object.
///
@@ -1398,9 +1399,14 @@ private:
/// @brief The affinator used to translate SCEVs to isl expressions.
SCEVAffinator Affinator;
- typedef MapVector<std::pair<AssertingVH<const Value>, int>,
- std::unique_ptr<ScopArrayInfo>>
+ typedef std::map<std::pair<AssertingVH<const Value>, int>,
+ std::unique_ptr<ScopArrayInfo>>
ArrayInfoMapTy;
+
+ typedef StringMap<std::unique_ptr<ScopArrayInfo>> ArrayNameMapTy;
+
+ typedef SetVector<ScopArrayInfo *> ArrayInfoSetTy;
+
/// @brief A map to remember ScopArrayInfo objects for all base pointers.
///
/// As PHI nodes may have two array info objects associated, we add a flag
@@ -1408,6 +1414,14 @@ private:
/// and the normal one.
ArrayInfoMapTy ScopArrayInfoMap;
+ /// @brief A map to remember ScopArrayInfo objects for all names of memory
+ /// references.
+ ArrayNameMapTy ScopArrayNameMap;
+
+ /// @brief A set to remember ScopArrayInfo objects.
+ /// @see Scop::ScopArrayInfoMap
+ ArrayInfoSetTy ScopArrayInfoSet;
+
/// @brief The assumptions under which this scop was built.
///
/// When constructing a scop sometimes the exact representation of a statement
@@ -1855,21 +1869,21 @@ public:
/// could be executed.
bool isEmpty() const { return Stmts.empty(); }
- typedef ArrayInfoMapTy::iterator array_iterator;
- typedef ArrayInfoMapTy::const_iterator const_array_iterator;
- typedef iterator_range<ArrayInfoMapTy::iterator> array_range;
- typedef iterator_range<ArrayInfoMapTy::const_iterator> const_array_range;
+ typedef ArrayInfoSetTy::iterator array_iterator;
+ typedef ArrayInfoSetTy::const_iterator const_array_iterator;
+ typedef iterator_range<ArrayInfoSetTy::iterator> array_range;
+ typedef iterator_range<ArrayInfoSetTy::const_iterator> const_array_range;
- inline array_iterator array_begin() { return ScopArrayInfoMap.begin(); }
+ inline array_iterator array_begin() { return ScopArrayInfoSet.begin(); }
- inline array_iterator array_end() { return ScopArrayInfoMap.end(); }
+ inline array_iterator array_end() { return ScopArrayInfoSet.end(); }
inline const_array_iterator array_begin() const {
- return ScopArrayInfoMap.begin();
+ return ScopArrayInfoSet.begin();
}
inline const_array_iterator array_end() const {
- return ScopArrayInfoMap.end();
+ return ScopArrayInfoSet.end();
}
inline array_range arrays() {
@@ -2148,10 +2162,21 @@ public:
///
/// @param ElementType The type of the elements stored in this array.
/// @param Kind The kind of the array info object.
+ /// @param BaseName The optional name of this memory reference.
const ScopArrayInfo *getOrCreateScopArrayInfo(Value *BasePtr,
Type *ElementType,
ArrayRef<const SCEV *> Sizes,
- ScopArrayInfo::MemoryKind Kind);
+ ScopArrayInfo::MemoryKind Kind,
+ const char *BaseName = nullptr);
+
+ /// @brief Create an array and return the corresponding ScopArrayInfo object.
+ ///
+ /// @param ElementType The type of the elements stored in this array.
+ /// @param BaseName The name of this memory reference.
+ /// @param Sizes The sizes of dimensions.
+ const ScopArrayInfo *createScopArrayInfo(Type *ElementType,
+ const std::string &BaseName,
+ const std::vector<unsigned> &Sizes);
/// @brief Return the cached ScopArrayInfo object for @p BasePtr.
///
@@ -2165,7 +2190,11 @@ public:
/// @param BasePtr The base pointer of the ScopArrayInfo object to invalidate.
/// @param Kind The Kind of the ScopArrayInfo object.
void invalidateScopArrayInfo(Value *BasePtr, ScopArrayInfo::MemoryKind Kind) {
- ScopArrayInfoMap.erase(std::make_pair(BasePtr, Kind));
+ auto It = ScopArrayInfoMap.find(std::make_pair(BasePtr, Kind));
+ if (It == ScopArrayInfoMap.end())
+ return;
+ ScopArrayInfoSet.remove(It->second.get());
+ ScopArrayInfoMap.erase(It);
}
void setContext(isl_set *NewContext);
@@ -2275,6 +2304,10 @@ public:
/// >0 for other loops in the SCoP
/// -1 if @p L is nullptr or there is no outermost loop in the SCoP
int getRelativeLoopDepth(const Loop *L) const;
+
+ /// @brief Find the ScopArrayInfo associated with an isl Id
+ /// that has name @p Name.
+ ScopArrayInfo *getArrayInfoByName(const std::string BaseName);
};
/// @brief Print Scop scop to raw_ostream O.
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=277263&r1=277262&r2=277263&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Sat Jul 30 04:25:51 2016
@@ -169,13 +169,21 @@ static const ScopArrayInfo *identifyBase
ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx,
ArrayRef<const SCEV *> Sizes, enum MemoryKind Kind,
- const DataLayout &DL, Scop *S)
+ const DataLayout &DL, Scop *S,
+ const char *BaseName)
: BasePtr(BasePtr), ElementType(ElementType), Kind(Kind), DL(DL), S(*S) {
std::string BasePtrName =
- getIslCompatibleName("MemRef_", BasePtr, Kind == MK_PHI ? "__phi" : "");
+ BaseName ? BaseName : getIslCompatibleName("MemRef_", BasePtr,
+ Kind == MK_PHI ? "__phi" : "");
Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
updateSizes(Sizes);
+
+ if (!BasePtr) {
+ BasePtrOriginSAI = nullptr;
+ return;
+ }
+
BasePtrOriginSAI = identifyBasePtrOriginSAI(S, BasePtr);
if (BasePtrOriginSAI)
const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
@@ -3133,7 +3141,9 @@ Scop::~Scop() {
// Explicitly release all Scop objects and the underlying isl objects before
// we relase the isl context.
Stmts.clear();
+ ScopArrayInfoSet.clear();
ScopArrayInfoMap.clear();
+ ScopArrayNameMap.clear();
AccFuncMap.clear();
}
@@ -3476,15 +3486,19 @@ void Scop::hoistInvariantLoads() {
isl_union_map_free(Writes);
}
-const ScopArrayInfo *
-Scop::getOrCreateScopArrayInfo(Value *BasePtr, Type *ElementType,
- ArrayRef<const SCEV *> Sizes,
- ScopArrayInfo::MemoryKind Kind) {
- auto &SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)];
+const ScopArrayInfo *Scop::getOrCreateScopArrayInfo(
+ Value *BasePtr, Type *ElementType, ArrayRef<const SCEV *> Sizes,
+ ScopArrayInfo::MemoryKind Kind, const char *BaseName) {
+ assert((BasePtr || BaseName) &&
+ "BasePtr and BaseName can not be nullptr at the same time.");
+ assert(!(BasePtr && BaseName) && "BaseName is redundant.");
+ auto &SAI = BasePtr ? ScopArrayInfoMap[std::make_pair(BasePtr, Kind)]
+ : ScopArrayNameMap[BaseName];
if (!SAI) {
auto &DL = getFunction().getParent()->getDataLayout();
SAI.reset(new ScopArrayInfo(BasePtr, ElementType, getIslCtx(), Sizes, Kind,
- DL, this));
+ DL, this, BaseName));
+ ScopArrayInfoSet.insert(SAI.get());
} else {
SAI->updateElementType(ElementType);
// In case of mismatching array sizes, we bail out by setting the run-time
@@ -3495,6 +3509,21 @@ Scop::getOrCreateScopArrayInfo(Value *Ba
return SAI.get();
}
+const ScopArrayInfo *
+Scop::createScopArrayInfo(Type *ElementType, const std::string &BaseName,
+ const std::vector<unsigned> &Sizes) {
+ auto *DimSizeType = Type::getInt64Ty(getSE()->getContext());
+ std::vector<const SCEV *> SCEVSizes;
+
+ for (auto size : Sizes)
+ SCEVSizes.push_back(getSE()->getConstant(DimSizeType, size, false));
+
+ auto *SAI =
+ getOrCreateScopArrayInfo(nullptr, ElementType, SCEVSizes,
+ ScopArrayInfo::MK_Array, BaseName.c_str());
+ return SAI;
+}
+
const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr,
ScopArrayInfo::MemoryKind Kind) {
auto *SAI = ScopArrayInfoMap[std::make_pair(BasePtr, Kind)].get();
@@ -3781,14 +3810,14 @@ void Scop::printArrayInfo(raw_ostream &O
OS << "Arrays {\n";
for (auto &Array : arrays())
- Array.second->print(OS);
+ Array->print(OS);
OS.indent(4) << "}\n";
OS.indent(4) << "Arrays (Bounds as pw_affs) {\n";
for (auto &Array : arrays())
- Array.second->print(OS, /* SizeAsPwAff */ true);
+ Array->print(OS, /* SizeAsPwAff */ true);
OS.indent(4) << "}\n";
}
@@ -4187,6 +4216,14 @@ int Scop::getRelativeLoopDepth(const Loo
return L->getLoopDepth() - OuterLoop->getLoopDepth();
}
+ScopArrayInfo *Scop::getArrayInfoByName(const std::string BaseName) {
+ for (auto &SAI : arrays()) {
+ if (SAI->getName() == BaseName)
+ return SAI;
+ }
+ return nullptr;
+}
+
//===----------------------------------------------------------------------===//
void ScopInfoRegionPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfoWrapperPass>();
Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=277263&r1=277262&r2=277263&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Sat Jul 30 04:25:51 2016
@@ -485,8 +485,7 @@ void BlockGenerator::createScalarInitial
Builder.SetInsertPoint(StartBB->getTerminator());
- for (auto &Pair : S.arrays()) {
- auto &Array = Pair.second;
+ for (auto &Array : S.arrays()) {
if (Array->getNumberOfDimensions() != 0)
continue;
if (Array->isPHIKind()) {
@@ -576,8 +575,7 @@ void BlockGenerator::createScalarFinaliz
}
void BlockGenerator::findOutsideUsers(Scop &S) {
- for (auto &Pair : S.arrays()) {
- auto &Array = Pair.second;
+ for (auto &Array : S.arrays()) {
if (Array->getNumberOfDimensions() != 0)
continue;
@@ -613,8 +611,7 @@ void BlockGenerator::createExitPHINodeMe
Builder.SetInsertPoint(OptExitBB->getTerminator());
- for (auto &Pair : S.arrays()) {
- auto &SAI = Pair.second;
+ for (auto &SAI : S.arrays()) {
auto *Val = SAI->getBasePtr();
// Only Value-like scalars need a merge PHI. Exit block PHIs receive either
Modified: polly/trunk/lib/CodeGen/CodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/CodeGeneration.cpp?rev=277263&r1=277262&r2=277263&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/CodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/CodeGeneration.cpp Sat Jul 30 04:25:51 2016
@@ -189,6 +189,7 @@ public:
isl_ast_node_free(AstRoot);
} else {
+ NodeBuilder.allocateNewArrays();
NodeBuilder.addParameters(S.getContext());
Modified: polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslNodeBuilder.cpp?rev=277263&r1=277262&r2=277263&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslNodeBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslNodeBuilder.cpp Sat Jul 30 04:25:51 2016
@@ -1157,6 +1157,32 @@ bool IslNodeBuilder::preloadInvariantEqu
return true;
}
+void IslNodeBuilder::allocateNewArrays() {
+ for (auto &SAI : S.arrays()) {
+ if (SAI->getBasePtr())
+ continue;
+
+ Type *NewArrayType = nullptr;
+ for (unsigned i = SAI->getNumberOfDimensions() - 1; i >= 1; i--) {
+ auto *DimSize = SAI->getDimensionSize(i);
+ unsigned UnsignedDimSize = static_cast<const SCEVConstant *>(DimSize)
+ ->getAPInt()
+ .getLimitedValue();
+
+ if (!NewArrayType)
+ NewArrayType = SAI->getElementType();
+
+ NewArrayType = ArrayType::get(NewArrayType, UnsignedDimSize);
+ }
+
+ auto InstIt =
+ Builder.GetInsertBlock()->getParent()->getEntryBlock().getTerminator();
+ Value *CreatedArray =
+ new AllocaInst(NewArrayType, SAI->getName(), &*InstIt);
+ SAI->setBasePtr(CreatedArray);
+ }
+}
+
bool IslNodeBuilder::preloadInvariantLoads() {
auto &InvariantEquivClasses = S.getInvariantAccesses();
Modified: polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp?rev=277263&r1=277262&r2=277263&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp Sat Jul 30 04:25:51 2016
@@ -794,7 +794,7 @@ SetVector<Value *> GPUNodeBuilder::getRe
findValues(Expr, SE, SubtreeValues);
for (auto &SAI : S.arrays())
- SubtreeValues.remove(SAI.second->getBasePtr());
+ SubtreeValues.remove(SAI->getBasePtr());
isl_space *Space = S.getParamSpace();
for (long i = 0; i < isl_space_dim(Space, isl_dim_param); i++) {
@@ -1379,7 +1379,7 @@ public:
}
for (auto &Array : S->arrays()) {
- auto Id = Array.second->getBasePtrId();
+ auto Id = Array->getBasePtrId();
Names = isl_id_to_ast_expr_set(Names, Id, isl_ast_expr_copy(Zero));
}
@@ -1550,9 +1550,7 @@ public:
/// @param PPCGProg The program to compute the arrays for.
void createArrays(gpu_prog *PPCGProg) {
int i = 0;
- for (auto &Element : S->arrays()) {
- ScopArrayInfo *Array = Element.second.get();
-
+ for (auto &Array : S->arrays()) {
std::string TypeName;
raw_string_ostream OS(TypeName);
@@ -1595,8 +1593,7 @@ public:
isl_union_map *getArrayIdentity() {
isl_union_map *Maps = isl_union_map_empty(S->getParamSpace());
- for (auto &Item : S->arrays()) {
- ScopArrayInfo *Array = Item.second.get();
+ for (auto &Array : S->arrays()) {
isl_space *Space = Array->getSpace();
Space = isl_space_map_from_set(Space);
isl_map *Identity = isl_map_identity(Space);
Modified: polly/trunk/lib/Exchange/JSONExporter.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Exchange/JSONExporter.cpp?rev=277263&r1=277262&r2=277263&view=diff
==============================================================================
--- polly/trunk/lib/Exchange/JSONExporter.cpp (original)
+++ polly/trunk/lib/Exchange/JSONExporter.cpp Sat Jul 30 04:25:51 2016
@@ -23,6 +23,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
#include "isl/constraint.h"
#include "isl/map.h"
#include "isl/printer.h"
@@ -96,6 +97,14 @@ struct JSONImporter : public ScopPass {
/// @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.
@@ -127,6 +136,35 @@ std::string JSONExporter::getFileName(Sc
void JSONExporter::printScop(raw_ostream &OS, Scop &S) const { S.print(OS); }
+/// 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) {
+ Json::Value Arrays;
+ std::string Buffer;
+ llvm::raw_string_ostream RawStringOstream(Buffer);
+
+ for (auto &SAI : S.arrays()) {
+ if (!SAI->isArrayKind())
+ continue;
+
+ Json::Value Array;
+ Array["name"] = SAI->getName();
+ for (unsigned i = 1; i < SAI->getNumberOfDimensions(); i++) {
+ SAI->getDimensionSize(i)->print(RawStringOstream);
+ Array["sizes"].append(RawStringOstream.str());
+ Buffer.clear();
+ }
+ SAI->getElementType()->print(RawStringOstream);
+ Array["type"] = RawStringOstream.str();
+ Buffer.clear();
+ Arrays.append(Array);
+ }
+ return Arrays;
+}
+
Json::Value JSONExporter::getJSON(Scop &S) const {
Json::Value root;
unsigned LineBegin, LineEnd;
@@ -142,6 +180,9 @@ Json::Value JSONExporter::getJSON(Scop &
root["context"] = S.getContextStr();
if (LineBegin != (unsigned)-1)
root["location"] = Location;
+
+ root["arrays"] = exportArrays(S);
+
root["statements"];
for (ScopStmt &Stmt : S) {
@@ -305,8 +346,28 @@ bool JSONImporter::importAccesses(Scop &
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 *NewOutId;
+
+ if (MA->isArrayKind()) {
+ NewOutId = isl_map_get_tuple_id(NewAccessMap, isl_dim_out);
+ auto *SAI = S.getArrayInfoByName(isl_id_get_name(NewOutId));
+ isl_id *OutId = isl_map_get_tuple_id(CurrentAccessMap, isl_dim_out);
+ auto *OutSAI = ScopArrayInfo::getFromId(OutId);
+ if (!SAI || SAI->getElementType() != OutSAI->getElementType()) {
+ errs() << "JScop file contains access function with undeclared "
+ "ScopArrayInfo\n";
+ isl_map_free(CurrentAccessMap);
+ isl_map_free(NewAccessMap);
+ isl_id_free(NewOutId);
+ return false;
+ }
+ isl_id_free(NewOutId);
+ NewOutId = SAI->getBasePtrId();
+ } else {
+ NewOutId = isl_map_get_tuple_id(CurrentAccessMap, isl_dim_out);
+ }
+
+ NewAccessMap = isl_map_set_tuple_id(NewAccessMap, isl_dim_out, NewOutId);
if (MA->isArrayKind()) {
// We keep the old alignment, thus we cannot allow accesses to memory
@@ -354,17 +415,19 @@ bool JSONImporter::importAccesses(Scop &
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)) {
+ auto NewAccessDomain = isl_map_domain(isl_map_copy(NewAccessMap));
+ auto CurrentAccessDomain = isl_map_domain(isl_map_copy(CurrentAccessMap));
+
+ if (!isl_set_has_equal_space(NewAccessDomain, CurrentAccessDomain)) {
errs() << "JScop file contains access function with incompatible "
<< "dimensions\n";
isl_map_free(CurrentAccessMap);
isl_map_free(NewAccessMap);
+ isl_set_free(NewAccessDomain);
+ isl_set_free(CurrentAccessDomain);
return false;
}
- 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());
CurrentAccessDomain =
@@ -400,6 +463,95 @@ bool JSONImporter::importAccesses(Scop &
return true;
}
+/// @brief Check whether @p SAI and @p Array represent the same array.
+bool areArraysEqual(ScopArrayInfo *SAI, Json::Value Array) {
+ std::string Buffer;
+ llvm::raw_string_ostream RawStringOstream(Buffer);
+
+ if (SAI->getName() != Array["name"].asCString())
+ return false;
+
+ if (SAI->getNumberOfDimensions() != Array["sizes"].size() + 1)
+ return false;
+
+ for (unsigned i = 0; i < Array["sizes"].size(); i++) {
+ SAI->getDimensionSize(i + 1)->print(RawStringOstream);
+ if (RawStringOstream.str() != Array["sizes"][i].asCString())
+ return false;
+ Buffer.clear();
+ }
+
+ SAI->getElementType()->print(RawStringOstream);
+ if (RawStringOstream.str() != Array["type"].asCString())
+ return false;
+
+ return true;
+}
+
+/// @brief Get the accepted primitive type from its textual representation
+/// @p TypeTextRepresentation.
+///
+/// @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) {
+ std::map<std::string, Type *> MapStrToType = {
+ {"void", Type::getVoidTy(LLVMContext)},
+ {"half", Type::getHalfTy(LLVMContext)},
+ {"float", Type::getFloatTy(LLVMContext)},
+ {"double", Type::getDoubleTy(LLVMContext)},
+ {"x86_fp80", Type::getX86_FP80Ty(LLVMContext)},
+ {"fp128", Type::getFP128Ty(LLVMContext)},
+ {"ppc_fp128", Type::getPPC_FP128Ty(LLVMContext)},
+ {"i1", Type::getInt1Ty(LLVMContext)},
+ {"i8", Type::getInt8Ty(LLVMContext)},
+ {"i16", Type::getInt16Ty(LLVMContext)},
+ {"i32", Type::getInt32Ty(LLVMContext)},
+ {"i64", Type::getInt64Ty(LLVMContext)},
+ {"i128", Type::getInt128Ty(LLVMContext)}};
+
+ auto It = MapStrToType.find(TypeTextRepresentation);
+ if (It != MapStrToType.end())
+ return It->second;
+
+ errs() << "Textual representation can not be parsed: "
+ << TypeTextRepresentation << "\n";
+ return nullptr;
+}
+
+bool JSONImporter::importArrays(Scop &S, Json::Value &JScop) {
+ Json::Value Arrays = JScop["arrays"];
+
+ if (Arrays.size() == 0)
+ return true;
+
+ unsigned ArrayIdx = 0;
+ for (auto &SAI : S.arrays()) {
+ if (!SAI->isArrayKind())
+ continue;
+ if (ArrayIdx + 1 > Arrays.size())
+ return false;
+ if (!areArraysEqual(SAI, Arrays[ArrayIdx]))
+ return false;
+ ArrayIdx++;
+ }
+
+ for (; ArrayIdx < Arrays.size(); ArrayIdx++) {
+ auto *ElementType = parseTextType(Arrays[ArrayIdx]["type"].asCString(),
+ S.getSE()->getContext());
+ if (!ElementType)
+ return false;
+ std::vector<unsigned> DimSizes;
+ for (unsigned i = 0; i < Arrays[ArrayIdx]["sizes"].size(); i++)
+ DimSizes.push_back(std::stoi(Arrays[ArrayIdx]["sizes"][i].asCString()));
+ S.createScopArrayInfo(ElementType, Arrays[ArrayIdx]["name"].asCString(),
+ DimSizes);
+ }
+
+ return true;
+}
+
bool JSONImporter::runOnScop(Scop &S) {
const Dependences &D =
getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
@@ -438,6 +590,11 @@ bool JSONImporter::runOnScop(Scop &S) {
if (!Success)
return false;
+
+ Success = importArrays(S, jscop);
+
+ if (!Success)
+ return false;
Success = importAccesses(S, jscop, DL);
Added: polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays.ll?rev=277263&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays.ll (added)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays.ll Sat Jul 30 04:25:51 2016
@@ -0,0 +1,76 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-import-jscop-dir=%S -polly-import-jscop -polly-import-jscop-postfix=transformed < %s 2>&1 | FileCheck %s
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-codegen -S < %s 2>&1 | FileCheck %s --check-prefix=CODEGEN
+;
+; for (i = 0; i < _PB_NI; i++)
+; for (j = 0; j < _PB_NJ; j++)
+; for (k = 0; k < _PB_NK; ++k)
+; B[i][j] = beta * A[i][k];
+;
+;
+; CHECK: Arrays {
+; CHECK: double MemRef_B[*][1024]; // Element size 8
+; CHECK: double MemRef_beta; // Element size 8
+; CHECK: double MemRef_A[*][1056]; // Element size 8
+; CHECK: double D[*][270336]; // Element size 8
+; CHECK: double E[*][270336][200000]; // Element size 8
+; CHECK: i64 F[*][270336]; // Element size 8
+;
+; CHECK:New access function '{ Stmt_bb12[i0, i1, i2] -> E[i2, i0] }'detected in JSCOP file
+;
+;define internal void @create_arrays(i32 %arg, i32 %arg1, i32 %arg2, double %arg3, double %beta, [1056 x double]* %A, [1024 x double]* %B, [1056 x double]* %arg7) #0 {
+;bb:
+; %beta.s2a = alloca double
+; %D = alloca [270336 x double]
+; %E = alloca [270336 x [200000 x double]]
+; %F = alloca [270336 x i64]
+; br label %bb8
+;
+; CODEGEN: %polly.access.cast.E = bitcast [270336 x [200000 x double]]* %E to double*
+; CODEGEN: %polly.access.mul.E = mul nsw i64 %polly.indvar33, 270336
+; CODEGEN: %polly.access.add.E = add nsw i64 %polly.access.mul.E, %polly.indvar
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-unknown"
+
+; Function Attrs: nounwind uwtable
+define internal void @create_arrays(i32 %arg, i32 %arg1, i32 %arg2, double %arg3, double %beta, [1056 x double]* %A, [1024 x double]* %B, [1056 x double]* %arg7) #0 {
+bb:
+ br label %bb8
+
+bb8: ; preds = %bb
+ br label %bb9
+
+bb9: ; preds = %bb23, %bb8
+ %tmp = phi i64 [ 0, %bb8 ], [ %tmp24, %bb23 ]
+ br label %bb10
+
+bb10: ; preds = %bb20, %bb9
+ %tmp11 = phi i64 [ 0, %bb9 ], [ %tmp21, %bb20 ]
+ br label %bb12
+
+bb12: ; preds = %bb12, %bb10
+ %tmp13 = phi i64 [ 0, %bb10 ], [ %tmp18, %bb12 ]
+ %tmp14 = getelementptr inbounds [1024 x double], [1024 x double]* %B, i64 %tmp, i64 %tmp13
+ %tmp15 = load double, double* %tmp14, align 8
+ %tmp16 = fmul double %tmp15, %beta
+ %tmp17 = getelementptr inbounds [1056 x double], [1056 x double]* %A, i64 %tmp, i64 %tmp11
+ store double %tmp16, double* %tmp17, align 8
+ %tmp18 = add nuw nsw i64 %tmp13, 1
+ %tmp19 = icmp ne i64 %tmp18, 1024
+ br i1 %tmp19, label %bb12, label %bb20
+
+bb20: ; preds = %bb12
+ %tmp21 = add nuw nsw i64 %tmp11, 1
+ %tmp22 = icmp ne i64 %tmp21, 1056
+ br i1 %tmp22, label %bb10, label %bb23
+
+bb23: ; preds = %bb20
+ %tmp24 = add nuw nsw i64 %tmp, 1
+ %tmp25 = icmp ne i64 %tmp24, 1056
+ br i1 %tmp25, label %bb9, label %bb26
+
+bb26: ; preds = %bb23
+ ret void
+}
+
+attributes #0 = { nounwind uwtable "target-cpu"="x86-64" "target-features"="+aes,+avx,+cmov,+cx16,+fxsr,+mmx,+pclmul,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt" }
Added: polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%bb9---%bb26.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%25bb9---%25bb26.jscop?rev=277263&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%bb9---%bb26.jscop (added)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%bb9---%bb26.jscop Sat Jul 30 04:25:51 2016
@@ -0,0 +1,37 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_B",
+ "sizes" : [ "1024" ],
+ "type" : "double"
+ },
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "1056" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "{ : }",
+ "name" : "%bb9---%bb26",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "{ Stmt_bb12[i0, i1, i2] -> MemRef_B[i0, i2] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "{ Stmt_bb12[i0, i1, i2] -> MemRef_beta[] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "{ Stmt_bb12[i0, i1, i2] -> MemRef_A[i0, i1] }"
+ }
+ ],
+ "domain" : "{ Stmt_bb12[i0, i1, i2] : 0 <= i0 <= 1055 and 0 <= i1 <= 1055 and 0 <= i2 <= 1023 }",
+ "name" : "Stmt_bb12",
+ "schedule" : "{ Stmt_bb12[i0, i1, i2] -> [i0, i1, i2] }"
+ }
+ ]
+}
Added: polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%bb9---%bb26.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%25bb9---%25bb26.jscop.transformed?rev=277263&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%bb9---%bb26.jscop.transformed (added)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/create_arrays___%bb9---%bb26.jscop.transformed Sat Jul 30 04:25:51 2016
@@ -0,0 +1,52 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_B",
+ "sizes" : [ "1024" ],
+ "type" : "double"
+ },
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "1056" ],
+ "type" : "double"
+ },
+ {
+ "name" : "D",
+ "sizes" : [ "270336" ],
+ "type" : "double"
+ },
+ {
+ "name" : "E",
+ "sizes" : [ "270336", "200000" ],
+ "type" : "double"
+ },
+ {
+ "name" : "F",
+ "sizes" : [ "270336" ],
+ "type" : "i64"
+ }
+ ],
+ "context" : "{ : }",
+ "name" : "%bb9---%bb26",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "{ Stmt_bb12[i0, i1, i2] -> E[i2, i0] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "{ Stmt_bb12[i0, i1, i2] -> MemRef_beta[] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "{ Stmt_bb12[i0, i1, i2] -> MemRef_A[i0, i1] }"
+ }
+ ],
+ "domain" : "{ Stmt_bb12[i0, i1, i2] : 0 <= i0 <= 1055 and 0 <= i1 <= 1055 and 0 <= i2 <= 1023 }",
+ "name" : "Stmt_bb12",
+ "schedule" : "{ Stmt_bb12[i0, i1, i2] -> [i0, i1, i2] }"
+ }
+ ]
+}
More information about the llvm-commits
mailing list