diff options
-rw-r--r-- | polly/lib/CodeGeneration.cpp | 67 |
1 files changed, 61 insertions, 6 deletions
diff --git a/polly/lib/CodeGeneration.cpp b/polly/lib/CodeGeneration.cpp index a8653bfe866..50eaa680c8e 100644 --- a/polly/lib/CodeGeneration.cpp +++ b/polly/lib/CodeGeneration.cpp @@ -44,6 +44,8 @@ #include "cloog/cloog.h" #include "cloog/isl/cloog.h" +#include "isl/aff.h" + #include <vector> #include <utility> @@ -83,6 +85,11 @@ Aligned("enable-polly-aligned", typedef DenseMap<const Value*, Value*> ValueMapT; typedef DenseMap<const char*, Value*> CharMapT; typedef std::vector<ValueMapT> VectorValueMapT; +typedef struct { + Value *BaseAddress; + Value *Result; + IRBuilder<> *Builder; +}IslPwAffUserInfo; // Create a new loop. // @@ -315,6 +322,58 @@ public: return vector; } + static Value* islAffToValue(__isl_take isl_aff *Aff, + IslPwAffUserInfo *UserInfo) { + assert(isl_aff_is_cst(Aff) && "Only constant access functions supported"); + + IRBuilder<> *Builder = UserInfo->Builder; + + isl_int OffsetIsl; + mpz_t OffsetMPZ; + + isl_int_init(OffsetIsl); + mpz_init(OffsetMPZ); + isl_aff_get_constant(Aff, &OffsetIsl); + isl_int_get_gmp(OffsetIsl, OffsetMPZ); + + Value *OffsetValue = NULL; + APInt Offset = APInt_from_MPZ(OffsetMPZ); + OffsetValue = ConstantInt::get(Builder->getContext(), Offset); + + mpz_clear(OffsetMPZ); + isl_int_clear(OffsetIsl); + isl_aff_free(Aff); + + return OffsetValue; + } + + static int mergeIslAffValues(__isl_take isl_set *Set, + __isl_take isl_aff *Aff, void *User) { + IslPwAffUserInfo *UserInfo = (IslPwAffUserInfo *)User; + + assert((UserInfo->Result == NULL) && "Result is already set." + "Currently only single isl_aff is supported"); + assert(isl_set_plain_is_universe(Set) + && "Code generation failed because the set is not universe"); + + UserInfo->Result = islAffToValue(Aff, UserInfo); + + isl_set_free(Set); + return 0; + } + + Value* islPwAffToValue(__isl_take isl_pw_aff *PwAff, Value *BaseAddress) { + IslPwAffUserInfo UserInfo; + UserInfo.BaseAddress = BaseAddress; + UserInfo.Result = NULL; + UserInfo.Builder = &Builder; + isl_pw_aff_foreach_piece(PwAff, mergeIslAffValues, &UserInfo); + assert(UserInfo.Result && "Code generation for isl_pw_aff failed"); + + isl_pw_aff_free(PwAff); + return UserInfo.Result; + } + /// @brief Get the memory access offset to be added to the base address std::vector <Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation, Value *BaseAddress) { @@ -324,13 +383,9 @@ public: assert((isl_map_dim(AccessRelation, isl_dim_out) == 1) && "Only single dimensional access functions supported"); - if (isl_map_plain_is_fixed(AccessRelation, isl_dim_out, - 0, &OffsetMPZ) == -1) - errs() << "Only fixed value access functions supported\n"; + isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0); + Value *OffsetValue = islPwAffToValue(PwAff, BaseAddress); - // Convert the offset from MPZ to Value*. - APInt Offset = APInt_from_MPZ(OffsetMPZ); - Value *OffsetValue = ConstantInt::get(Builder.getContext(), Offset); PointerType *BaseAddressType = dyn_cast<PointerType>( BaseAddress->getType()); Type *ArrayTy = BaseAddressType->getElementType(); |