[LLVMdev] -indvars issues?

Eric Lu eirc.lew at gmail.com
Wed Jun 19 18:21:07 PDT 2013


It works, thank you, Andy.


On Thu, Jun 20, 2013 at 12:45 AM, Andrew Trick <atrick at apple.com> wrote:

>
> On Jun 19, 2013, at 1:04 AM, Eric Lu <eirc.lew at gmail.com> wrote:
>
> It seems the options still does not work, or I have misunderstood what you
> said.
>
> The command:
> clang -g   -I/home/lxj/software/llvmsvn/include -emit-llvm $1.c -c -o
> $1.bc
> opt  -debug --debug-pass=Structure -scalar-evolution -loop-rotate $1.bc -o
> $1-loop.bc
> opt -S $1-loop.bc -o $1-loop.ll
>
>
> 1) The source code:
>
> #include <stdio.h>
> #define N 100
> int main()
> {
>
>   int i, j, a[N];
>   int *ptr = (int*) malloc(sizeof(int) *100);
>   i = 100;
>   for( ; i > 0;  i+= -3)
>   {
>     j = i;
>     a[j] = i + 2;;
>     *ptr = i + 1;
>     ptr++;
>   }
>   printf("a[10] = %d \n", a[10]);
>
>   return 0;
> }
>
> 2) The output llvm files, loop.ll, only shows loop related codes.
> tore i32* %0, i32** %ptr, align 8, !dbg !20
>   *store i32 100, i32* %i, align 4, !dbg !21*
>   %1 = load i32* %i, align 4, !dbg !22
>   %cmp1 = icmp sgt i32 %1, 0, !dbg !22
>   br i1 %cmp1, label %for.body.lr.ph, label %for.end, !dbg !22
>
> for.body.lr.ph:                                   ; preds = %entry
>   br label %for.body, !dbg !22
>
> for.body:                                         ; preds = %for.inc, %
> for.body.lr.ph
>   %2 = load i32* %i, align 4, !dbg !24
>   store i32 %2, i32* %j, align 4, !dbg !24
>   %3 = load i32* %i, align 4, !dbg !26
>   %add = add nsw i32 %3, 2, !dbg !26
>   %4 = load i32* %j, align 4, !dbg !26
>   %idxprom = sext i32 %4 to i64, !dbg !26
>   %arrayidx = getelementptr inbounds [100 x i32]* %a, i32 0, i64 %idxprom,
> !dbg !26
>   store i32 %add, i32* %arrayidx, align 4, !dbg !26
>   %5 = load i32* %i, align 4, !dbg !27
>   %add1 = add nsw i32 %5, 1, !dbg !27
>   %6 = load i32** %ptr, align 8, !dbg !27
>   store i32 %add1, i32* %6, align 4, !dbg !27
>   %7 = load i32** %ptr, align 8, !dbg !28
>   %incdec.ptr = getelementptr inbounds i32* %7, i32 1, !dbg !28
>   store i32* %incdec.ptr, i32** %ptr, align 8, !dbg !28
>   br label %for.inc, !dbg !29
>
> for.inc:                                          ; preds = %for.body
>   %8 = load i32* %i, align 4, !dbg !22
>   %add2 = add nsw i32 %8, -3, !dbg !22
>   store i32 %add2, i32* %i, align 4, !dbg !22
>   %9 = load i32* %i, align 4, !dbg !22
>   %cmp = icmp sgt i32 %9, 0, !dbg !22
>   br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge, !dbg !22
>
> for.cond.for.end_crit_edge:                       ; preds = %for.inc
>   br label %for.end, !dbg !22
>
> for.end:                                          ; preds =
> %for.cond.for.end_crit_edge, %entry
>   %arrayidx3 = getelementptr inbounds [100 x i32]* %a, i32 0, i64 10, !dbg
> !30
>
>
> It’s a good idea to run mem2reg and simplifycfg before anything else:
> opt -mem2reg -simplifycfg -loop-rotate -indvars
>
> define i32 @main() #0 {
>   %a = alloca [100 x i32], align 16
>   %1 = bitcast [100 x i32]* %a to i8*
>   call void @llvm.lifetime.start(i64 400, i8* %1) #1
>   %2 = call i8* @malloc(i64 400)
>   %3 = bitcast i8* %2 to i32*
>   br label %4
>
> ; <label>:4                                       ; preds = %0, %4
>   %indvars.iv = phi i64 [ 100, %0 ], [ %indvars.iv.next, %4 ]
>   %ptr.01 = phi i32* [ %3, %0 ], [ %10, %4 ]
>   %5 = add nsw i64 %indvars.iv, 2
>   %6 = getelementptr inbounds [100 x i32]* %a, i32 0, i64 %indvars.iv
>   %7 = trunc i64 %5 to i32
>   store i32 %7, i32* %6, align 4, !tbaa !0
>   %8 = add nsw i64 %indvars.iv, 1
>   %9 = trunc i64 %8 to i32
>   store i32 %9, i32* %ptr.01, align 4, !tbaa !0
>   %10 = getelementptr inbounds i32* %ptr.01, i32 1
>   %indvars.iv.next = add i64 %indvars.iv, -3
>   %11 = trunc i64 %indvars.iv.next to i32
>   %12 = icmp sgt i32 %11, 0
>   br i1 %12, label %4, label %13
>
> ; <label>:13                                      ; preds = %4
>   %14 = getelementptr inbounds [100 x i32]* %a, i32 0, i64 10
>   %15 = load i32* %14, align 4, !tbaa !0
>   %16 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x
> i8]* @.str, i32 0, i32 0), i32 %15)
>   %17 = bitcast [100 x i32]* %a to i8*
>   call void @llvm.lifetime.end(i64 400, i8* %17) #1
>   ret i32 0
> }
>
> Now the loop is in a canonical form while the induction variables are
> still just the way you’ve written them. (The compiler isn’t going to
> destructively rewrite your code for no expected benefit).
>
> opt -analyze -scalar-evolution shows the canonical form of each induction
> variable:
>
>   %6 = getelementptr inbounds [100 x i32]* %a, i32 0, i64 %indvars.iv
>   -->  {(400 + %a),+,-12}<%4> Exits: (4 + %a)
>
>   %10 = getelementptr inbounds i32* %ptr.01, i32 1
>   -->  {(4 + %2),+,4}<nw><%4> Exits: (136 + %2)
>
> llc -loop-reduce is a codegen pass that rewrites the induction variables
> in the target’s preferred form.
>
> For IR readability, you may want the induction variables to be rewritten
> in terms of a 0..N loop counter. That’s a useful tool but not part of
> LLVM’s standard optimization pipeline. You could add such a pass on a local
> branch using either the LoopStrengthReduce pass or the 3.1 source as
> reference.
>
> -Andy
>
>
> On Wed, Jun 19, 2013 at 1:32 AM, Andrew Trick <atrick at apple.com> wrote:
>
>>
>> On Jun 18, 2013, at 6:08 AM, eric.lew <eirc.lew at gmail.com> wrote:
>>
>> It seems there is no -enable-iv-rewrite now in llvm3.2,  and it suggest
>> -enable-load-pre, but it still does not work.
>>
>> So, how to active the transform?
>>
>>
>> Eric,
>>
>> Loops are canonicalized with -loop-rotate, which implicitly calls
>> -loop-simplify first.
>>
>> The canonical form of the induction variables is expressed in the
>> ScalarEvolution analysis.
>>
>> -indvars simplifies inductions variables, mainly by eliminating sign
>> extension, but does not rewrite them into a canonical form.
>>
>> -Andy
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130620/245d0593/attachment.html>


More information about the llvm-dev mailing list