[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