[llvm-commits] [polly] r153319 - in /polly/trunk: lib/ test/CodeGen/MemAccess/

Tobias Grosser grosser at fim.uni-passau.de
Fri Mar 23 01:21:23 PDT 2012


Author: grosser
Date: Fri Mar 23 03:21:22 2012
New Revision: 153319

URL: http://llvm.org/viewvc/llvm-project?rev=153319&view=rev
Log:
CodeGen: Full support for isl_pw expressions in modified access functions.

This also adds support for modifiable write accesses (until now only read
accesses where supported). We currently do not derive an exact type for the
expression, but assume that i64 is good enough. This will be improved in future
patches.

Contributed by: Yabin Hu <yabin.hwu at gmail.com>

Added:
    polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.c
    polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.ll
    polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop
    polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withconst
    polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withoutconst
Modified:
    polly/trunk/lib/CodeGeneration.cpp
    polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_constant_offset.ll
    polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_simple.ll

Modified: polly/trunk/lib/CodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGeneration.cpp?rev=153319&r1=153318&r2=153319&view=diff
==============================================================================
--- polly/trunk/lib/CodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGeneration.cpp Fri Mar 23 03:21:22 2012
@@ -154,7 +154,8 @@
 
 class IslGenerator {
 public:
-  IslGenerator(IRBuilder<> &Builder) : Builder(Builder) {}
+  IslGenerator(IRBuilder<> &Builder, std::vector<Value *> &IVS) :
+    Builder(Builder), IVS(IVS) {}
   Value *generateIslInt(__isl_take isl_int Int);
   Value *generateIslAff(__isl_take isl_aff *Aff);
   Value *generateIslPwAff(__isl_take isl_pw_aff *PwAff);
@@ -166,6 +167,7 @@
   } IslGenInfo;
 
   IRBuilder<> &Builder;
+  std::vector<Value *> &IVS;
   static int mergeIslAffValues(__isl_take isl_set *Set,
                                __isl_take isl_aff *Aff, void *User);
 };
@@ -180,18 +182,46 @@
 }
 
 Value *IslGenerator::generateIslAff(__isl_take isl_aff *Aff) {
-  assert(isl_aff_is_cst(Aff) && "Only constant access functions supported");
+  Value *Result;
   Value *ConstValue;
   isl_int ConstIsl;
 
   isl_int_init(ConstIsl);
   isl_aff_get_constant(Aff, &ConstIsl);
   ConstValue = generateIslInt(ConstIsl);
+  Type *Ty = Builder.getInt64Ty();
 
+  // FIXME: We should give the constant and coefficients the right type. Here
+  // we force it into i64.
+  Result = Builder.CreateSExtOrBitCast(ConstValue, Ty);
+
+  unsigned int NbInputDims = isl_aff_dim(Aff, isl_dim_in);
+
+  assert((IVS.size() == NbInputDims) && "The Dimension of Induction Variables"
+         "must match the dimension of the affine space.");
+
+  isl_int CoefficientIsl;
+  isl_int_init(CoefficientIsl);
+
+  for (unsigned int i = 0; i < NbInputDims; ++i) {
+    Value *CoefficientValue;
+    isl_aff_get_coefficient(Aff, isl_dim_in, i, &CoefficientIsl);
+
+    if (isl_int_is_zero(CoefficientIsl))
+      continue;
+
+    CoefficientValue = generateIslInt(CoefficientIsl);
+    CoefficientValue = Builder.CreateIntCast(CoefficientValue, Ty, true);
+    Value *IV = Builder.CreateIntCast(IVS[i], Ty, true);
+    Value *PAdd = Builder.CreateMul(CoefficientValue, IV, "p_mul_coeff");
+    Result = Builder.CreateAdd(Result, PAdd, "p_sum_coeff");
+  }
+
+  isl_int_clear(CoefficientIsl);
   isl_int_clear(ConstIsl);
   isl_aff_free(Aff);
 
-  return ConstValue;
+  return Result;
 }
 
 int IslGenerator::mergeIslAffValues(__isl_take isl_set *Set,
@@ -266,13 +296,14 @@
 
   /// @brief Get the memory access offset to be added to the base address
   std::vector<Value*> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
-                                            Value *BaseAddress);
+                                           Value *BaseAddress, ValueMapT &BBMap,
+                                           ValueMapT &GlobalMap);
 
   /// @brief Get the new operand address according to the changed access in
   ///        JSCOP file.
   Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
                              Value *BaseAddress, const Value *OldOperand,
-                             ValueMapT &BBMap);
+                             ValueMapT &BBMap, ValueMapT &GlobalMap);
 
   /// @brief Generate the operand address
   Value *generateLocationAccessed(const Instruction *Inst,
@@ -282,6 +313,9 @@
   Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap,
                             ValueMapT &GlobalMap);
 
+  Value *generateScalarStore(const StoreInst *store, ValueMapT &BBMap,
+                             ValueMapT &GlobalMap);
+
   /// @brief Copy a single Instruction.
   ///
   /// This copies a single Instruction and updates references to old values
@@ -367,23 +401,29 @@
     NewInst->setName("p_" + Inst->getName());
 }
 
-std::vector <Value*> BlockGenerator::getMemoryAccessIndex(
-  __isl_keep isl_map *AccessRelation, Value *BaseAddress) {
+std::vector<Value*> BlockGenerator::getMemoryAccessIndex(
+  __isl_keep isl_map *AccessRelation, Value *BaseAddress,
+  ValueMapT &BBMap, ValueMapT &GlobalMap) {
+
   assert((isl_map_dim(AccessRelation, isl_dim_out) == 1)
          && "Only single dimensional access functions supported");
 
+  std::vector<Value *> IVS;
+  for (unsigned i = 0; i < Statement.getNumIterators(); ++i) {
+    const Value *OriginalIV = Statement.getInductionVariableForDimension(i);
+    Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap);
+    IVS.push_back(NewIV);
+  }
+
   isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
-  IslGenerator IslGen(Builder);
+  IslGenerator IslGen(Builder, IVS);
   Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
 
-  PointerType *BaseAddressType = dyn_cast<PointerType>(
-    BaseAddress->getType());
-  Type *ArrayTy = BaseAddressType->getElementType();
-  Type *ArrayElementType = dyn_cast<ArrayType>(ArrayTy)->getElementType();
-  OffsetValue = Builder.CreateSExtOrBitCast(OffsetValue, ArrayElementType);
+  Type *Ty = Builder.getInt64Ty();
+  OffsetValue = Builder.CreateIntCast(OffsetValue, Ty, true);
 
   std::vector<Value*> IndexArray;
-  Value *NullValue = Constant::getNullValue(ArrayElementType);
+  Value *NullValue = Constant::getNullValue(Ty);
   IndexArray.push_back(NullValue);
   IndexArray.push_back(OffsetValue);
   return IndexArray;
@@ -391,9 +431,10 @@
 
 Value *BlockGenerator::getNewAccessOperand(
   __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, const Value
-  *OldOperand, ValueMapT &BBMap) {
+  *OldOperand, ValueMapT &BBMap, ValueMapT &GlobalMap) {
   std::vector<Value*> IndexArray = getMemoryAccessIndex(NewAccessRelation,
-                                                        BaseAddress);
+                                                        BaseAddress,
+                                                        BBMap, GlobalMap);
   Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray,
                                         "p_newarrayidx_");
   return NewOperand;
@@ -417,7 +458,7 @@
   } else {
     Value *BaseAddress = const_cast<Value*>(Access.getBaseAddr());
     NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, Pointer,
-                                     BBMap);
+                                     BBMap, GlobalMap);
   }
 
   isl_map_free(CurrentAccessRelation);
@@ -436,6 +477,17 @@
   return ScalarLoad;
 }
 
+Value *BlockGenerator::generateScalarStore(const StoreInst *Store,
+                                           ValueMapT &BBMap,
+                                           ValueMapT &GlobalMap) {
+  const Value *Pointer = Store->getPointerOperand();
+  Value *NewPointer = generateLocationAccessed(Store, Pointer, BBMap,
+                                               GlobalMap);
+  Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap);
+
+  return Builder.CreateStore(ValueOperand, NewPointer);
+}
+
 void BlockGenerator::copyInstruction(const Instruction *Inst,
                                      ValueMapT &BBMap, ValueMapT &GlobalMap) {
   // Terminator instructions control the control flow. They are explicitly
@@ -448,6 +500,11 @@
     return;
   }
 
+  if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
+    BBMap[Store] = generateScalarStore(Store, BBMap, GlobalMap);
+    return;
+  }
+
   copyInstScalar(Inst, BBMap, GlobalMap);
 }
 

Added: polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.c?rev=153319&view=auto
==============================================================================
--- polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.c (added)
+++ polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.c Fri Mar 23 03:21:22 2012
@@ -0,0 +1,9 @@
+int A[1040];
+
+int codegen_simple_md() {
+  for (int i = 0; i < 32; ++i)
+    for (int j = 0; j < 32; ++j)
+      A[32*i+j] = 100;
+
+  return 0;
+}

Added: polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.ll?rev=153319&view=auto
==============================================================================
--- polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.ll (added)
+++ polly/trunk/test/CodeGen/MemAccess/codegen_simple_md.ll Fri Mar 23 03:21:22 2012
@@ -0,0 +1,64 @@
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withconst -polly-codegen %s -S | FileCheck -check-prefix=WITHCONST %s
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withoutconst -polly-codegen %s -S | FileCheck -check-prefix=WITHOUTCONST %s
+; ModuleID = 'codegen_simple_md.s'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+target triple = "i386-pc-linux-gnu"
+
+ at A = common global [1040 x i32] zeroinitializer, align 4
+
+define i32 @codegen_simple_md() nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc4, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+  %exitcond1 = icmp ne i32 %i.0, 32
+  br i1 %exitcond1, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 32
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %mul = shl nsw i32 %i.0, 5
+  %add = add nsw i32 %mul, %j.0
+  %arrayidx = getelementptr inbounds [1040 x i32]* @A, i32 0, i32 %add
+  store i32 100, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc4
+
+for.inc4:                                         ; preds = %for.end
+  %inc5 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end6:                                         ; preds = %for.cond
+  ret i32 0
+}
+
+; WITHCONST:  %4 = sext i32 %2 to i64
+; WITHCONST:  %p_mul_coeff = mul i64 16, %4
+; WITHCONST:  %p_sum_coeff = add i64 5, %p_mul_coeff
+; WITHCONST:  %5 = sext i32 %3 to i64
+; WITHCONST:  %p_mul_coeff6 = mul i64 2, %5
+; WITHCONST:  %p_sum_coeff7 = add i64 %p_sum_coeff, %p_mul_coeff6
+; WITHCONST:  %p_newarrayidx_ = getelementptr [1040 x i32]* @A, i64 0, i64 %p_sum_coeff7
+; WITHCONST:  store i32 100, i32* %p_newarrayidx_
+
+; WITHOUTCONST:  %4 = sext i32 %2 to i64
+; WITHOUTCONST:  %p_mul_coeff = mul i64 16, %4
+; WITHOUTCONST:  %p_sum_coeff = add i64 0, %p_mul_coeff
+; WITHOUTCONST:  %5 = sext i32 %3 to i64
+; WITHOUTCONST:  %p_mul_coeff6 = mul i64 2, %5
+; WITHOUTCONST:  %p_sum_coeff7 = add i64 %p_sum_coeff, %p_mul_coeff6
+; WITHOUTCONST:  %p_newarrayidx_ = getelementptr [1040 x i32]* @A, i64 0, i64 %p_sum_coeff7
+; WITHOUTCONST:  store i32 100, i32* %p_newarrayidx_

Added: polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%25for.cond---%25for.end6.jscop?rev=153319&view=auto
==============================================================================
--- polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop (added)
+++ polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop Fri Mar 23 03:21:22 2012
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[32i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 31 and i1 >= 0 and i1 <= 31 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0] }"
+      }
+   ]
+}

Added: polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withconst
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%25for.cond---%25for.end6.jscop.transformed%2Bwithconst?rev=153319&view=auto
==============================================================================
--- polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withconst (added)
+++ polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withconst Fri Mar 23 03:21:22 2012
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[16i0 + 2i1 + 5] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 31 and i1 >= 0 and i1 <= 31 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0] }"
+      }
+   ]
+}

Added: polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withoutconst
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%25for.cond---%25for.end6.jscop.transformed%2Bwithoutconst?rev=153319&view=auto
==============================================================================
--- polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withoutconst (added)
+++ polly/trunk/test/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withoutconst Fri Mar 23 03:21:22 2012
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[16i0 + 2i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 31 and i1 >= 0 and i1 <= 31 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0] }"
+      }
+   ]
+}

Modified: polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_constant_offset.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_constant_offset.ll?rev=153319&r1=153318&r2=153319&view=diff
==============================================================================
--- polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_constant_offset.ll (original)
+++ polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_constant_offset.ll Fri Mar 23 03:21:22 2012
@@ -31,4 +31,4 @@
 for.end:                                          ; preds = %for.cond
   ret i32 0
 }
-; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i32 0, i32 10)
+; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i64 0, i64 10)

Modified: polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_simple.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_simple.ll?rev=153319&r1=153318&r2=153319&view=diff
==============================================================================
--- polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_simple.ll (original)
+++ polly/trunk/test/CodeGen/MemAccess/memaccess_codegen_simple.ll Fri Mar 23 03:21:22 2012
@@ -31,4 +31,4 @@
 for.end:                                          ; preds = %for.cond
   ret i32 0
 }
-; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i32 0, i32 0)
+; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i64 0, i64 0)





More information about the llvm-commits mailing list