delinearization

Tobias Grosser tobias at grosser.es
Wed Apr 9 01:21:22 PDT 2014


On 04/08/2014 11:38 PM, Sebastian Pop wrote:
> Tobias Grosser wrote:
>> On 04/04/2014 11:06 PM, Sebastian Pop wrote:
>>> Hi,
>>>
>>> here is the updated version of the patch that passes all the make check-polly
>>> tests: yay! (I don't have cloog around, so I haven't checked those tests.)
>>
>> The cloog tests need to be updated. There are three solutions
>>
>> 1) We write a clang-cmp tool that does this semantically
>> 2) You install it briefly and update the tests
>
> I installed cloog and checked with it before I committed the patch.
> All tests are passing.
>
> However, when I enable delinearization by default, 2 cloog tests are failing:
> Tobi, could you please have a look at these two?
>
> test/Cloog/CodeGen/matmul_vec.ll
> test/Cloog/CodeGen/MemAccess/codegen_simple_md.ll
>
>
> These are failing with a JScop error complaining about inconsistent array access
> functions (or something else...)

Yes, I looked into them. We can fix them by updating the .jscop files.

When looking into these test cases, I have seen that you also 
delinearize access functions to fixed size, non linear arrays. This is 
very tempting, but for test/Cloog/CodeGen/matmul_vec.ll this currently 
does not work correctly.

MemRef_A[i0 + 1024i2]

is translated to

MemRef_A[i0, 1024i2]

What is the reason to even try to delinearize non-parametric accesses? 
Doing so is not necessary to increase the precision of our analysis and 
if we get it wrong it has actually negative effects. Also, I believe 
delinearizing such accesses is inherently hard. I personally have the 
feeling limiting ourselves to delinearize arrays with symbolic sizes
is a safer bet.

>> 3) You commit and I fix later.
>>
>> I would prefer 1), understand that 2) is easier and if necessary, we
>> can also go for 3).
>>
>>> The only changes wrt. previous patch are:
>>> - add a flag -polly-delinearize (similar to -da-delinearize)
>>> - normalize the last subscript with respect to the size of elements in the array.
>>
>> Nice, that this fixed the remaining issues.
>>
>>> Ok to commit?
>>
>> Yes, despite the CLooG test cases this looks good.
>
> No cloog tests were failing on my side, so our build bots should be happy with
> my last commit.
>
> I have started triaging the bugs in the nightly test-suite when enabling
> -polly-delinearization.  I have fixed a couple of bugs already: that just shows
> that all this code was never really tested...  I will continue a bit on fixing
> everything that fails in SCEV->delinearize and on the -polly-delinearize side.

The delinearization bug I opened is still open.

I looked at the way we do delinearization and especially at examples of 
non-static size arrays. I attached the following example:

; void foo(long n, long m, double A[n][32]) {
;   for (long i = 0; i < n; i++)
;     for (long j = 0; j < m; j++)
;       A[i][j] = A[i][j+i];
; }

In the inner loop, we get the following delinearization:

Inst:  %val = load double* %arrayidx.load
In Loop with Header: for.j
AddRec: {{%A,+,(33 * sizeof(double))}<%for.i>,+,sizeof(double)}<%for.j>
Base offset: %A
ArrayDecl[UnknownSize][33] with elements of sizeof(double) bytes.
ArrayRef[{0,+,1}<nuw><nsw><%for.i>][{0,+,1}<nuw><nsw><%for.j>]

Inst:  store double %val, double* %arrayidx.store
In Loop with Header: for.j
AddRec: {{%A,+,(32 * sizeof(double))}<%for.i>,+,sizeof(double)}<%for.j>
Base offset: %A
ArrayDecl[UnknownSize][32] with elements of sizeof(double) bytes.
ArrayRef[{0,+,1}<nuw><nsw><%for.i>][{0,+,1}<nuw><nsw><%for.j>]

For the load we derive a size of 33 elements in the inner dimension, for 
the store a size of 32 elements. This is inconsistent and to me it is 
unclear how to derive a common delinearization. For symbolic sizes the 
problem should be a lot simpler.

Cheers,
Tobias

-------------- next part --------------
; RUN: opt < %s -analyze -delinearize | FileCheck %s

; Derived from the following code:
;
; void foo(long n, long m, double A[n][32]) {
;   for (long i = 0; i < n; i++)
;     for (long j = 0; j < m; j++)
;       A[i][i] = A[i][j];
; }

; AddRec: {{%A,+,(8 * %m)}<%for.i>,+,8}<%for.j>
; CHECK: Base offset: %A
; CHECK: ArrayDecl[UnknownSize][%m] with elements of sizeof(double) bytes.
; CHECK: ArrayRef[{0,+,1}<nuw><nsw><%for.i>][{0,+,1}<nuw><nsw><%for.j>]

; AddRec: {(-8 + (8 * %m) + %A),+,(8 * %m)}<%for.i>
; CHECK: Base offset: %A
; CHECK: ArrayDecl[UnknownSize] with elements of sizeof(double) bytes.
; CHECK: ArrayRef[{(-1 + %m),+,%m}<%for.i>]

define void @foo(i64 %n, i64 %m, double* %A) {
entry:
  br label %for.i

for.i:
  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
  %tmp = mul nsw i64 %i, 32
  br label %for.j

for.j:
  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j ]
  %vlaarrayidx.load = add i64 %j, %tmp
  %vlaarrayidx.store = add i64 %i, %tmp
  %arrayidx.load = getelementptr inbounds double* %A, i64 %vlaarrayidx.load
  %arrayidx.store = getelementptr inbounds double* %A, i64 %vlaarrayidx.store
  %val = load double* %arrayidx.load
  store double %val, double* %arrayidx.store
  %j.inc = add nsw i64 %j, 1
  %j.exitcond = icmp eq i64 %j.inc, %m
  br i1 %j.exitcond, label %for.i.inc, label %for.j

for.i.inc:
  %i.inc = add nsw i64 %i, 1
  %i.exitcond = icmp eq i64 %i.inc, %n
  br i1 %i.exitcond, label %end, label %for.i

end:
  ret void
}



More information about the llvm-commits mailing list