[llvm-commits] [PATCH] Disable instruction hoisting

Tobias Grosser grosser at fim.uni-passau.de
Sat Aug 14 05:00:55 PDT 2010


Hi,

I would like to contribute a patch that allows to disable instruction 
hoisting in the SCEVExpander. It does not change the current behaviour 
of any code, but will allow polly to use it to generate so called 
independent blocks.

I already had a discussion with Dan that there might be a solution that 
does not require to patch the SCEVExpander. However I did not find one.
Therefore I will explain how we use the SCEVExpander with disabled 
instruction hoisting. Hope someone can help me to either find a 
solution, that does not need a patched SCEVExpander, or if there is no 
practical one someone could approve this patch.

The idea is if there is e.g. a cfg region that looks like this.
foo (int Parameter) {
   for i
     for j {
     { BB 1:
       temp = i + j + Parameter;
       A [temp] = 0;
     }
     { BB 2:
       temp2 = temp + 2i;
       B[temp2] = 0;
     }
   }
}

We want to move those bbs into a completely different loop nest and 
possible change the order of the basic blocks.
This works easily for BB 1, as it is only referencing either loop ivs, 
that will be provided externally or parameters, which are also available.
BB 2 however is referencing a scalar value, that is not available, if BB 
2 is either eliminated or moved to another place:

foo (int Parameter) {
   for x
     for y
       for z {
     {
       i = x + y;
       j = floord(x + 14z, 5);
     }
     { BB 2:
       temp2 = temp + 2i;    << temp is not yet defined.
       B[temp2] = 0;
     }
     { BB 1:
       temp = i + j;
       A [temp] = 0;
     }
}

The solution we used was to SCEVExpand all scalars into the same basic 
block. Such that the trivial calculations needed to recalulate a 
variable from a set of induction variables and/or parameters are always 
available.
In this example the code with the updated BB 2 looks like this.

foo (int Parameter) {
   for i
     for j {
     { BB 1:
       temp = i + j + Parameter;
       A [temp] = 0;
     }
     { BB 2:
       auto_temp = i + j + Parameter;
       temp2 = auto_temp + 2i;
       B[temp2] = 0;
     }
   }
}

It can easily be moved in a new loop nest without taking care of any 
trivial scalar dependences.

foo (int Parameter) {
   for x
     for y
       for z {
     {
       i = min(x,y);
       j = floord(x + 14z, 5);
     }
     { BB 2:
       auto_temp = i + j + Parameter;
       temp2 = auto_temp + 2i;       << No problem any more.
       B[temp2] = 0;
     }
     { BB 1:
       temp = i + j;
       A [temp] = 0;
     }
}

A solution that would work without patch scev expander is to somehow
change the scevs describing the original statements.

Looking at this code:

void independent_blocks() {
   int i;
   int temp;
   for (i = 0; i < N; i++) {
     temp = i;

     A[temp] = 1;
   }
}

Relevant LLVM-IR produces this SCEVs:
   %indvar = phi i64 [ %indvar.next, %3 ], [ 0, %0 ] ; <i64> [#uses=3]
   -->  {0,+,1}<%1>		Exits: 1024
   %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar ; 
<i32*> [#uses=1]
   -->  {@A,+,4}<%1>		Exits: (4096 + @A)
   %indvar.next = add i64 %indvar, 1               ; <i64> [#uses=1]
   -->  {1,+,1}<%1>		Exits: 1025

In this example I would like to generate a SCEV that has the same value 
as e.g. {@A,+,4}<%1>, but does not depend on any loops. Instead it 
contains a reference to some new instructions %new_i that contains the 
loop iteration value.
Is there a good way to achieve this or do you know any other feasible 
solution to achieve this?

In case there is no good one, I would love to hear some comments about 
the patch proposed.

Thanks a lot
Tobi


-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-SCEVExpander-Allow-to-disable-instruction-hoisting.patch
Type: text/x-diff
Size: 9111 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20100814/1e9e1cef/attachment.patch>


More information about the llvm-commits mailing list