[llvm-commits] [polly] r146972 - in /polly/trunk: include/polly/TempScopInfo.h lib/Analysis/ScopDetection.cpp lib/Analysis/ScopInfo.cpp lib/Analysis/TempScopInfo.cpp test/CodeGen/simple_nonaffine_loop.c test/CodeGen/simple_nonaffine_loop.ll test/ScopInfo/simple_nonaffine_loop.ll test/ScopInfo/simple_nonaffine_loop_not.ll

Tobias Grosser grosser at fim.uni-passau.de
Tue Dec 20 02:43:14 PST 2011


Author: grosser
Date: Tue Dec 20 04:43:14 2011
New Revision: 146972

URL: http://llvm.org/viewvc/llvm-project?rev=146972&view=rev
Log:
Support non-affine access functions in Polly.

In case we can not analyze an access function, we do not discard the SCoP, but
assume conservatively that all memory accesses that can be derived from our base
pointer may be accessed.

Patch provided by: Marcello Maggioni <hayarms at gmail.com>

Added:
    polly/trunk/test/CodeGen/simple_nonaffine_loop.c
    polly/trunk/test/CodeGen/simple_nonaffine_loop.ll
    polly/trunk/test/ScopInfo/simple_nonaffine_loop.ll
    polly/trunk/test/ScopInfo/simple_nonaffine_loop_not.ll
Modified:
    polly/trunk/include/polly/TempScopInfo.h
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/lib/Analysis/TempScopInfo.cpp

Modified: polly/trunk/include/polly/TempScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/TempScopInfo.h?rev=146972&r1=146971&r2=146972&view=diff
==============================================================================
--- polly/trunk/include/polly/TempScopInfo.h (original)
+++ polly/trunk/include/polly/TempScopInfo.h Tue Dec 20 04:43:14 2011
@@ -45,12 +45,13 @@
 private:
   unsigned ElemBytes;
   TypeKind Type;
+  bool IsAffine;
 
 public:
   explicit IRAccess (TypeKind Type, const Value *BaseAddress,
-                     const SCEV *Offset, unsigned elemBytes)
+                     const SCEV *Offset, unsigned elemBytes, bool Affine)
     : BaseAddress(BaseAddress), Offset(Offset),
-      ElemBytes(elemBytes), Type(Type) {}
+      ElemBytes(elemBytes), Type(Type), IsAffine(Affine) {}
 
   enum TypeKind getType() const { return Type; }
 
@@ -60,7 +61,10 @@
 
   unsigned getElemSizeInBytes() const { return ElemBytes; }
 
+  bool isAffine() const { return IsAffine; }
+
   bool isRead() const { return Type == READ; }
+
 };
 
 class Comparison {

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=146972&r1=146971&r2=146972&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Tue Dec 20 04:43:14 2011
@@ -79,6 +79,11 @@
                cl::desc("Ignore possible aliasing of the array bases"),
                cl::Hidden, cl::init(false));
 
+static cl::opt<bool>
+AllowNonAffine("polly-allow-nonaffine",
+               cl::desc("Allow non affine access functions in arrays"),
+               cl::Hidden, cl::init(false));
+
 //===----------------------------------------------------------------------===//
 // Statistics.
 
@@ -245,7 +250,7 @@
 
   AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
 
-  if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE, BaseValue))
+  if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE, BaseValue) && !AllowNonAffine)
     INVALID(AffFunc, "Bad memory address " << *AccessFunction);
 
   // FIXME: Alias Analysis thinks IntToPtrInst aliases with alloca instructions

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=146972&r1=146971&r2=146972&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Tue Dec 20 04:43:14 2011
@@ -312,9 +312,16 @@
   Type = Access.isRead() ? Read : Write;
   statement = Statement;
 
-  isl_pw_aff *Affine = SCEVAffinator::getPwAff(Statement, Access.getOffset());
   BaseAddr = Access.getBase();
 
+  if (!Access.isAffine()) {
+    Type = (Type == Read) ? Read : MayWrite;
+    AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
+    return;
+  }
+
+  isl_pw_aff *Affine = SCEVAffinator::getPwAff(Statement, Access.getOffset());
+
   setBaseName();
 
   // Devide the access function by the size of the elements in the array.

Modified: polly/trunk/lib/Analysis/TempScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/TempScopInfo.cpp?rev=146972&r1=146971&r2=146972&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/TempScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/TempScopInfo.cpp Tue Dec 20 04:43:14 2011
@@ -98,11 +98,15 @@
         dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction));
 
       assert(BasePointer && "Could not find base pointer");
-
       AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
+
+      bool IsAffine = isAffineExpr(&R, AccessFunction, *SE,
+                                   BasePointer->getValue());
+
       Functions.push_back(std::make_pair(IRAccess(Type,
                                                   BasePointer->getValue(),
-                                                  AccessFunction, Size),
+                                                  AccessFunction, Size,
+                                                  IsAffine),
                                          &Inst));
     }
   }

Added: polly/trunk/test/CodeGen/simple_nonaffine_loop.c
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/simple_nonaffine_loop.c?rev=146972&view=auto
==============================================================================
--- polly/trunk/test/CodeGen/simple_nonaffine_loop.c (added)
+++ polly/trunk/test/CodeGen/simple_nonaffine_loop.c Tue Dec 20 04:43:14 2011
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+int main()
+{
+	int A[1024*1024];
+	int i;
+	for (i = 0; i < 1024; i++)
+		A[i*i] = 2*i;
+
+	printf("Random Value: %d", A[rand() % 1024*1024]);
+
+	return 0;
+}

Added: polly/trunk/test/CodeGen/simple_nonaffine_loop.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/CodeGen/simple_nonaffine_loop.ll?rev=146972&view=auto
==============================================================================
--- polly/trunk/test/CodeGen/simple_nonaffine_loop.ll (added)
+++ polly/trunk/test/CodeGen/simple_nonaffine_loop.ll Tue Dec 20 04:43:14 2011
@@ -0,0 +1,43 @@
+; RUN: opt %loadPolly %defaultOpts -O3 -polly-cloog -polly-allow-nonaffine -analyze %s | FileCheck %s
+; ModuleID = 'simple_nonaffine_loop.c'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.2"
+
+ at .str = private unnamed_addr constant [17 x i8] c"Random Value: %d\00", align 1
+
+define i32 @main() nounwind uwtable ssp {
+entry:
+  %A = alloca [1048576 x i32], align 16
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %0 = phi i32 [ 0, %entry.split ], [ %1, %for.body ]
+  %mul = mul i32 %0, 2
+  %mul1 = mul nsw i32 %0, %0
+  %idxprom1 = zext i32 %mul1 to i64
+  %arrayidx = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom1
+  store i32 %mul, i32* %arrayidx, align 4
+  %1 = add nsw i32 %0, 1
+  %exitcond = icmp ne i32 %1, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body
+  %call = call i32 @rand() nounwind
+  %rem = srem i32 %call, 1024
+  %mul2 = shl nsw i32 %rem, 10
+  %idxprom3 = sext i32 %mul2 to i64
+  %arrayidx4 = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom3
+  %2 = load i32* %arrayidx4, align 16
+  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i64 0, i64 0), i32 %2) nounwind
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+declare i32 @rand()
+; CHECK: for (c2=0;c2<=1023;c2++) {
+; CHECK:  Stmt_for_body(c2);
+; CHECK: }

Added: polly/trunk/test/ScopInfo/simple_nonaffine_loop.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/simple_nonaffine_loop.ll?rev=146972&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/simple_nonaffine_loop.ll (added)
+++ polly/trunk/test/ScopInfo/simple_nonaffine_loop.ll Tue Dec 20 04:43:14 2011
@@ -0,0 +1,41 @@
+; RUN: opt %loadPolly %defaultOpts -polly-scops -polly-allow-nonaffine -analyze %s | FileCheck %s
+; ModuleID = 'simple_nonaffine_loop.c'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.2"
+
+ at .str = private unnamed_addr constant [17 x i8] c"Random Value: %d\00", align 1
+
+define i32 @main() nounwind uwtable ssp {
+entry:
+  %A = alloca [1048576 x i32], align 16
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %0 = phi i32 [ 0, %entry.split ], [ %1, %for.body ]
+  %mul = mul i32 %0, 2
+  %mul1 = mul nsw i32 %0, %0
+  %idxprom1 = zext i32 %mul1 to i64
+  %arrayidx = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom1
+  store i32 %mul, i32* %arrayidx, align 4
+  %1 = add nsw i32 %0, 1
+  %exitcond = icmp ne i32 %1, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body
+  %call = call i32 @rand() nounwind
+  %rem = srem i32 %call, 1024
+  %mul2 = shl nsw i32 %rem, 10
+  %idxprom3 = sext i32 %mul2 to i64
+  %arrayidx4 = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom3
+  %2 = load i32* %arrayidx4, align 16
+  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i64 0, i64 0), i32 %2) nounwind
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+declare i32 @rand()
+; CHECK:                { Stmt_for_body[i0] -> MemRef_A[o0] };

Added: polly/trunk/test/ScopInfo/simple_nonaffine_loop_not.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/simple_nonaffine_loop_not.ll?rev=146972&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/simple_nonaffine_loop_not.ll (added)
+++ polly/trunk/test/ScopInfo/simple_nonaffine_loop_not.ll Tue Dec 20 04:43:14 2011
@@ -0,0 +1,41 @@
+; RUN: opt %loadPolly %defaultOpts -polly-scops -analyze %s | not FileCheck %s
+; ModuleID = 'simple_nonaffine_loop.c'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.2"
+
+ at .str = private unnamed_addr constant [17 x i8] c"Random Value: %d\00", align 1
+
+define i32 @main() nounwind uwtable ssp {
+entry:
+  %A = alloca [1048576 x i32], align 16
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %0 = phi i32 [ 0, %entry.split ], [ %1, %for.body ]
+  %mul = mul i32 %0, 2
+  %mul1 = mul nsw i32 %0, %0
+  %idxprom1 = zext i32 %mul1 to i64
+  %arrayidx = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom1
+  store i32 %mul, i32* %arrayidx, align 4
+  %1 = add nsw i32 %0, 1
+  %exitcond = icmp ne i32 %1, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body
+  %call = call i32 @rand() nounwind
+  %rem = srem i32 %call, 1024
+  %mul2 = shl nsw i32 %rem, 10
+  %idxprom3 = sext i32 %mul2 to i64
+  %arrayidx4 = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom3
+  %2 = load i32* %arrayidx4, align 16
+  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i64 0, i64 0), i32 %2) nounwind
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+declare i32 @rand()
+; CHECK:                { Stmt_for_body[i0] -> MemRef_A[o0] };





More information about the llvm-commits mailing list