summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/lib/CodeGeneration.cpp67
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();
OpenPOWER on IntegriCloud