[llvm-dev] loop unrolling introduces conditional branch

Jeremy Lakeman via llvm-dev llvm-dev at lists.llvm.org
Fri Aug 21 08:05:25 PDT 2015


There's been some recent noise on the mailing list about requiring
-fno-rtti;
http://lists.llvm.org/pipermail/llvm-dev/2015-August/089010.html

Could that be it?

On Sat, Aug 22, 2015 at 12:21 AM, Xiangyang Guo via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Hi, James and Philip, Thanks for your help.
>
> Based on your advice, I downloaded llvm-3.7. However, with this new
> version of LLVM, I have the following errors when I compile my previous
> code:
>
> g++ -o parser main.o  `llvm-config --libs all` `llvm-config --ldflags
> --system-libs` -lpthread -ldl -rdynamic -ltinfo
> main.o:(.data.rel.ro._ZTIN4llvm17GetElementPtrInstE[_ZTIN4llvm17GetElementPtrInstE]+0x10):
> undefined reference to `typeinfo for llvm::Instruction'
> main.o:(.data.rel.ro._ZTIN4llvm8ICmpInstE[_ZTIN4llvm8ICmpInstE]+0x10):
> undefined reference to `typeinfo for llvm::CmpInst'
>
> BTW, in my code, I use LLVM API (IRBuilder and so on) to generate one
> Module and then use PassManager to add several passes. And my Makefile is
> pretty simple, it looks like this:
>
> ***********************************************************************************************
> all: parser
>
> OBJS = main.o    \
>
> LLVMCONFIG = llvm-config
> CPPFLAGS = `$(LLVMCONFIG) --cxxflags` -std=c++11
> LDFLAGS = `$(LLVMCONFIG) --ldflags --system-libs` -lpthread -ldl -rdynamic
> -ltinfo
> LIBS = `$(LLVMCONFIG) --libs all`
>
> clean:
> $(RM) -rf parser $(OBJS)
>
> %.o: %.cpp
> g++ -g -c $(CPPFLAGS) -o $@ $<
>
>
> parser: $(OBJS)
> g++ -o $@ $(OBJS) $(LIBS) $(LDFLAGS)
>
> **********************************************************************************************
> Do you have any idea? Thanks a lot.
>
> Regards,
>
> Xiangyang
>
> On Thu, Aug 20, 2015 at 2:23 PM, James Molloy <james at jamesmolloy.co.uk>
> wrote:
>
>> Hi Xiangyang,
>>
>> The algorithm for loop unrolling was changed post-3.5 to do more what
>> you'd expect. If you use 3.6 or 3.7 you'll likely get better results.
>>
>> Cheers,
>>
>> James
>>
>> On Thu, 20 Aug 2015 at 18:09 Philip Reames via llvm-dev <
>> llvm-dev at lists.llvm.org> wrote:
>>
>>> On 08/20/2015 07:38 AM, Xiangyang Guo via llvm-dev wrote:
>>>
>>> Hi,
>>>
>>> I want to use loop unrolling pass, however, I find that loop unrolling
>>> will introduces conditional branch at end of every "unrolled" part. For
>>> example, consider the following code
>>>
>>> *void foo( int n, int array_x[])*
>>> *{*
>>> *    for (int i=0; i < n; i++)*
>>> *     array_x[i] = i; *
>>> *}*
>>>
>>> Then I use this command "opt-3.5 try.bc -mem2reg -loops -loop-simplify
>>> -loop-rotate -lcssa -indvars -loop-unroll -unroll-count=3 -simplifycfg -S",
>>> it gives me this IR:
>>>
>>> *define void @_Z3fooiPi(i32 %n, i32* %array_x) #0 {*
>>> *  %1 = icmp slt i32 0, %n*
>>> *  br i1 %1, label %.lr.ph <http://lr.ph/>, label %._crit_edge*
>>>
>>> *.lr.ph <http://lr.ph/>:                                           ;
>>> preds = %0, %7*
>>> *  %indvars.iv = phi i64 [ %indvars.iv.next.2, %7 ], [ 0, %0 ]*
>>> *  %2 = getelementptr inbounds i32* %array_x, i64 %indvars.iv*
>>> *  %3 = trunc i64 %indvars.iv to i32*
>>> *  store i32 %3, i32* %2*
>>> *  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1*
>>> *  %lftr.wideiv = trunc i64 %indvars.iv.next to i32*
>>> *  %exitcond = icmp ne i32 %lftr.wideiv, %n*
>>> *  br i1 %exitcond, label %4, label %._crit_edge*
>>>
>>> *._crit_edge:                                      ; preds = %.lr.ph
>>> <http://lr.ph/>, %4, %7, %0*
>>> *  ret void*
>>>
>>> *; <label>:4                                       ; preds = %.lr.ph
>>> <http://lr.ph/>*
>>> *  %5 = getelementptr inbounds i32* %array_x, i64 %indvars.iv.next*
>>> *  %6 = trunc i64 %indvars.iv.next to i32*
>>> *  store i32 %6, i32* %5*
>>> *  %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv.next, 1*
>>> *  %lftr.wideiv.1 = trunc i64 %indvars.iv.next.1 to i32*
>>> *  %exitcond.1 = icmp ne i32 %lftr.wideiv.1, %n*
>>> *  br i1 %exitcond.1, label %7, label %._crit_edge*
>>>
>>> *; <label>:7                                       ; preds = %4*
>>> *  %8 = getelementptr inbounds i32* %array_x, i64 %indvars.iv.next.1*
>>> *  %9 = trunc i64 %indvars.iv.next.1 to i32*
>>> *  store i32 %9, i32* %8*
>>> *  %indvars.iv.next.2 = add nuw nsw i64 %indvars.iv.next.1, 1*
>>> *  %lftr.wideiv.2 = trunc i64 %indvars.iv.next.2 to i32*
>>> *  %exitcond.2 = icmp ne i32 %lftr.wideiv.2, %n*
>>> *  br i1 %exitcond.2, label %.lr.ph <http://lr.ph/>, label %._crit_edge*
>>> *}*
>>>
>>> As you can see, at the end of BB <label>4 and BB<label>7 there are
>>> "add", "icmp" and "br" instrcutions to check the boundary. I understand
>>> this is for the correctness. However, I would expect the loop unrolling can
>>> change my code to something like this:
>>>
>>> *void foo( int n, int array_x[])*
>>> *{*
>>> *    int j = n%3;*
>>> *    int m = n - j;*
>>> *    for (int i=0; i < m; i+=3){*
>>> *     array_x[i] = i;*
>>> *     array_x[i+1] = i+1;*
>>> *     array_x[i+2] = i+2; *
>>> *    }*
>>> *    for(i=m; i<n; i++)*
>>> *     array_x[i] = i;        *
>>> *}*
>>>
>>> In this case, the BB<label>4 and BB<label>7 will do not have the "add",
>>> "icmp" and "br" instructions because these BBs can be merged together.
>>>
>>> How can I achieve this? Thanks.
>>>
>>> One - rather heavy weight - way to do this would be to add the -irce
>>> pass after the loop unroll step.  InductiveRangeCheckElimination will
>>> introduce a post loop so as to eliminate the range checks in the inner
>>> loop.  This might not be the ideal transformation for this code, but it
>>> might get you closer to what you want.
>>>
>>> A couple of caveats:
>>> - 3.5 isn't recent enough to have a stable IRCE.  Download ToT.
>>> - IRCE requires profiling information on the branches.  I'd start by
>>> manually annotating your IR to see if it works, then exploring a profile
>>> build if it does.
>>>
>>> For the record, teaching the unroller to do this transformation (or a
>>> creating a new pass) would seem interesting.  You might check with Chandler
>>> and/or Michael (see recent review threads) for what their plans in this
>>> area are.
>>>
>>>
>>> Regards,
>>>
>>> Xiangyang
>>>
>>>
>>> _______________________________________________
>>> LLVM Developers mailing listllvm-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> llvm-dev at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150822/b1264e58/attachment.html>


More information about the llvm-dev mailing list