<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Mar 25, 2014 at 11:21 AM, Evan Cheng <span dir="ltr"><<a href="mailto:evan.cheng@apple.com" target="_blank">evan.cheng@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Manman,<br>
<br>
I have a couple of questions.<br>
<br>
1. Is there any measurable compile time impact?<br></blockquote><div>I will look into that and follow up with data.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

2. Could the CSRCost be target specific? Is it sensitive to the numbers of CSRs and caller-saved registers?</blockquote><div>Yes, CSRCost can be target specific (I will work on that).</div><div>The main performance advantage is removing push|pop from prologue|epilogue, for using callee-saved registers.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> I see the heuristics is already taking into account the cost of spilling. Could it be different for different register classes?<br>
</blockquote><div>We currently model cost of spilling with block frequency, without considering different register classes.</div><div>The cost may vary with different register classes.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
Also, can you add more comments to explain why sometimes it’s spilling is preferable to using CSRs?<br></blockquote><div>Sure.</div><div><br></div><div>Thanks,</div><div>Manman </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
Thanks,<br>
<br>
Evan<br>
<div class="HOEnZb"><div class="h5"><br>
On Mar 24, 2014, at 5:16 PM, Manman Ren <<a href="mailto:manman.ren@gmail.com">manman.ren@gmail.com</a>> wrote:<br>
<br>
> Author: mren<br>
> Date: Mon Mar 24 19:16:25 2014<br>
> New Revision: 204690<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=204690&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=204690&view=rev</a><br>
> Log:<br>
> Register Allocator: check other options before using a CSR for the first time.<br>
><br>
> When register allocator's stage is RS_Spill, we choose spill over using the CSR<br>
> for the first time, if the spill cost is lower than CSRCost.<br>
> When register allocator's stage is < RS_Split, we choose pre-splitting over<br>
> using the CSR for the first time, if the cost of splitting is lower than<br>
> CSRCost.<br>
><br>
> CSRCost is set with command-line option "regalloc-csr-first-time-cost". The<br>
> default value is 0 to generate the same codes as before this commit.<br>
><br>
> With a value of 15 (1 << 14 is the entry frequency), I measured performance<br>
> gain of 3% on 253.perlbmk and 1.7% on 197.parser, with instrumented PGO,<br>
> on an arm device.<br>
><br>
> rdar://16162005<br>
><br>
> Added:<br>
>    llvm/trunk/test/CodeGen/AArch64/ragreedy-csr.ll<br>
> Modified:<br>
>    llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=204690&r1=204689&r2=204690&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=204690&r1=204689&r2=204690&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Mon Mar 24 19:16:25 2014<br>
> @@ -71,6 +71,12 @@ static cl::opt<unsigned> LastChanceRecol<br>
>              " interference at a time"),<br>
>     cl::init(8));<br>
><br>
> +// FIXME: Find a good default for this flag and remove the flag.<br>
> +static cl::opt<unsigned><br>
> +CSRFirstTimeCost("regalloc-csr-first-time-cost",<br>
> +              cl::desc("Cost for first time use of callee-saved register."),<br>
> +              cl::init(0), cl::Hidden);<br>
> +<br>
> static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator",<br>
>                                        createGreedyRegisterAllocator);<br>
><br>
> @@ -310,7 +316,7 @@ private:<br>
>   unsigned calculateRegionSplitCost(LiveInterval &VirtReg,<br>
>                                     AllocationOrder &Order,<br>
>                                     BlockFrequency &BestCost,<br>
> -                                    unsigned &NumCands);<br>
> +                                    unsigned &NumCands, bool IgnoreCSR);<br>
>   /// Perform region splitting.<br>
>   unsigned doRegionSplit(LiveInterval &VirtReg, unsigned BestCand,<br>
>                          bool HasCompact,<br>
> @@ -1257,7 +1263,8 @@ unsigned RAGreedy::tryRegionSplit(LiveIn<br>
>   }<br>
><br>
>   unsigned BestCand =<br>
> -      calculateRegionSplitCost(VirtReg, Order, BestCost, NumCands);<br>
> +      calculateRegionSplitCost(VirtReg, Order, BestCost, NumCands,<br>
> +                               false/*IgnoreCSR*/);<br>
><br>
>   // No solutions found, fall back to single block splitting.<br>
>   if (!HasCompact && BestCand == NoCand)<br>
> @@ -1269,10 +1276,15 @@ unsigned RAGreedy::tryRegionSplit(LiveIn<br>
> unsigned RAGreedy::calculateRegionSplitCost(LiveInterval &VirtReg,<br>
>                                             AllocationOrder &Order,<br>
>                                             BlockFrequency &BestCost,<br>
> -                                            unsigned &NumCands) {<br>
> +                                            unsigned &NumCands,<br>
> +                                            bool IgnoreCSR) {<br>
>   unsigned BestCand = NoCand;<br>
>   Order.rewind();<br>
>   while (unsigned PhysReg = Order.next()) {<br>
> +   if (unsigned CSR = RegClassInfo.getLastCalleeSavedAlias(PhysReg))<br>
> +     if (IgnoreCSR && !MRI->isPhysRegUsed(CSR))<br>
> +       continue;<br>
> +<br>
>     // Discard bad candidates before we run out of interference cache cursors.<br>
>     // This will only affect register classes with a lot of registers (>32).<br>
>     if (NumCands == IntfCache.getMaxCursors()) {<br>
> @@ -2099,10 +2111,49 @@ unsigned RAGreedy::selectOrSplitImpl(Liv<br>
>                                      SmallVectorImpl<unsigned> &NewVRegs,<br>
>                                      SmallVirtRegSet &FixedRegisters,<br>
>                                      unsigned Depth) {<br>
> +  unsigned CostPerUseLimit = ~0u;<br>
>   // First try assigning a free register.<br>
>   AllocationOrder Order(VirtReg.reg, *VRM, RegClassInfo);<br>
> -  if (unsigned PhysReg = tryAssign(VirtReg, Order, NewVRegs))<br>
> -    return PhysReg;<br>
> +  if (unsigned PhysReg = tryAssign(VirtReg, Order, NewVRegs)) {<br>
> +    // We check other options if we are using a CSR for the first time.<br>
> +    bool CSRFirstUse = false;<br>
> +    if (unsigned CSR = RegClassInfo.getLastCalleeSavedAlias(PhysReg))<br>
> +      if (!MRI->isPhysRegUsed(CSR))<br>
> +        CSRFirstUse = true;<br>
> +<br>
> +    BlockFrequency CSRCost(CSRFirstTimeCost);<br>
> +    if (getStage(VirtReg) == RS_Spill && CSRFirstUse && NewVRegs.empty() &&<br>
> +        CSRFirstTimeCost > 0 && VirtReg.isSpillable()) {<br>
> +      // We choose spill over using the CSR for the first time if the spill cost<br>
> +      // is lower than CSRCost.<br>
> +      SA->analyze(&VirtReg);<br>
> +      if (calcSpillCost() >= CSRCost)<br>
> +        return PhysReg;<br>
> +<br>
> +      // We are going to spill, set CostPerUseLimit to 1 to make sure that<br>
> +      // we will not use a callee-saved register in tryEvict.<br>
> +      CostPerUseLimit = 1;<br>
> +    }<br>
> +    else if (getStage(VirtReg) < RS_Split && CSRFirstUse &&<br>
> +             NewVRegs.empty() && CSRFirstTimeCost > 0) {<br>
> +      // We choose pre-splitting over using the CSR for the first time if<br>
> +      // the cost of splitting is lower than CSRCost.<br>
> +      SA->analyze(&VirtReg);<br>
> +      unsigned NumCands = 0;<br>
> +      unsigned BestCand =<br>
> +        calculateRegionSplitCost(VirtReg, Order, CSRCost, NumCands,<br>
> +                                 true/*IgnoreCSR*/);<br>
> +      if (BestCand == NoCand)<br>
> +        // Use the CSR if we can't find a region split below CSRCost.<br>
> +        return PhysReg;<br>
> +<br>
> +      // Perform the actual pre-splitting.<br>
> +      doRegionSplit(VirtReg, BestCand, false/*HasCompact*/, NewVRegs);<br>
> +      if (!NewVRegs.empty())<br>
> +        return 0;<br>
> +    } else<br>
> +      return PhysReg;<br>
> +  }<br>
><br>
>   LiveRangeStage Stage = getStage(VirtReg);<br>
>   DEBUG(dbgs() << StageName[Stage]<br>
> @@ -2112,7 +2163,7 @@ unsigned RAGreedy::selectOrSplitImpl(Liv<br>
>   // queue. The RS_Split ranges already failed to do this, and they should not<br>
>   // get a second chance until they have been split.<br>
>   if (Stage != RS_Split)<br>
> -    if (unsigned PhysReg = tryEvict(VirtReg, Order, NewVRegs))<br>
> +    if (unsigned PhysReg = tryEvict(VirtReg, Order, NewVRegs, CostPerUseLimit))<br>
>       return PhysReg;<br>
><br>
>   assert(NewVRegs.empty() && "Cannot append to existing NewVRegs");<br>
><br>
> Added: llvm/trunk/test/CodeGen/AArch64/ragreedy-csr.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/ragreedy-csr.ll?rev=204690&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/ragreedy-csr.ll?rev=204690&view=auto</a><br>

> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/AArch64/ragreedy-csr.ll (added)<br>
> +++ llvm/trunk/test/CodeGen/AArch64/ragreedy-csr.ll Mon Mar 24 19:16:25 2014<br>
> @@ -0,0 +1,297 @@<br>
> +; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -regalloc=greedy -regalloc-csr-first-time-cost=15 | FileCheck %s<br>
> +<br>
> +; This testing case is reduced from 197.parser prune_match function.<br>
> +; We make sure that we do not use callee-saved registers (x19 to x25).<br>
> +; rdar://16162005<br>
> +<br>
> +; CHECK-LABEL: prune_match:<br>
> +; CHECK: entry<br>
> +; CHECK: str x30, [sp<br>
> +; CHECK-NOT: stp x25,<br>
> +; CHECK-NOT: stp x23, x24<br>
> +; CHECK-NOT: stp x21, x22<br>
> +; CHECK-NOT: stp x19, x20<br>
> +; CHECK: if.end<br>
> +; CHECK: return<br>
> +; CHECK: ldr x30, [sp<br>
> +; CHECK-NOT: ldp x19, x20<br>
> +; CHECK-NOT: ldp x21, x22<br>
> +; CHECK-NOT: ldp x23, x24<br>
> +; CHECK-NOT: ldp x25,<br>
> +<br>
> +%struct.List_o_links_struct = type { i32, i32, i32, %struct.List_o_links_struct* }<br>
> +%struct.Connector_struct = type { i16, i16, i8, i8, %struct.Connector_struct*, i8* }<br>
> +%struct._RuneLocale = type { [8 x i8], [32 x i8], i32 (i8*, i64, i8**)*, i32 (i32, i8*, i64, i8**)*, i32, [256 x i32], [256 x i32], [256 x i32], %struct._RuneRange, %struct._RuneRange, %struct._RuneRange, i8*, i32, i32, %struct._RuneCharClass* }<br>

> +%struct._RuneRange = type { i32, %struct._RuneEntry* }<br>
> +%struct._RuneEntry = type { i32, i32, i32, i32* }<br>
> +%struct._RuneCharClass = type { [14 x i8], i32 }<br>
> +%struct.Exp_struct = type { i8, i8, i8, i8, %union.anon }<br>
> +%union.anon = type { %struct.E_list_struct* }<br>
> +%struct.E_list_struct = type { %struct.E_list_struct*, %struct.Exp_struct* }<br>
> +%struct.domain_struct = type { i8*, i32, %struct.List_o_links_struct*, i32, i32, %struct.d_tree_leaf_struct*, %struct.domain_struct* }<br>
> +%struct.d_tree_leaf_struct = type { %struct.domain_struct*, i32, %struct.d_tree_leaf_struct* }<br>
> +@_DefaultRuneLocale = external global %struct._RuneLocale<br>
> +declare i32 @__maskrune(i32, i64) #7<br>
> +define fastcc i32 @prune_match(%struct.Connector_struct* nocapture readonly %a, %struct.Connector_struct* nocapture readonly %b) #9 {<br>
> +entry:<br>
> +  %label56 = bitcast %struct.Connector_struct* %a to i16*<br>
> +  %0 = load i16* %label56, align 2<br>
> +  %label157 = bitcast %struct.Connector_struct* %b to i16*<br>
> +  %1 = load i16* %label157, align 2<br>
> +  %cmp = icmp eq i16 %0, %1<br>
> +  br i1 %cmp, label %if.end, label %return, !prof !988<br>
> +if.end:<br>
> +  %priority = getelementptr inbounds %struct.Connector_struct* %a, i64 0, i32 2<br>
> +  %2 = load i8* %priority, align 1<br>
> +  %priority5 = getelementptr inbounds %struct.Connector_struct* %b, i64 0, i32 2<br>
> +  %3 = load i8* %priority5, align 1<br>
> +  %string = getelementptr inbounds %struct.Connector_struct* %a, i64 0, i32 5<br>
> +  %4 = load i8** %string, align 8<br>
> +  %string7 = getelementptr inbounds %struct.Connector_struct* %b, i64 0, i32 5<br>
> +  %5 = load i8** %string7, align 8<br>
> +  br label %while.cond<br>
> +while.cond:<br>
> +  %lsr.iv27 = phi i64 [ %lsr.iv.next28, %if.end17 ], [ 0, %if.end ]<br>
> +  %scevgep55 = getelementptr i8* %4, i64 %lsr.iv27<br>
> +  %6 = load i8* %scevgep55, align 1<br>
> +  %idxprom.i.i = sext i8 %6 to i64<br>
> +  %isascii.i.i224 = icmp sgt i8 %6, -1<br>
> +  br i1 %isascii.i.i224, label %cond.true.i.i, label %cond.false.i.i, !prof !181<br>
> +cond.true.i.i:<br>
> +  %arrayidx.i.i = getelementptr inbounds %struct._RuneLocale* @_DefaultRuneLocale, i64 0, i32 5, i64 %idxprom.i.i<br>
> +  %7 = load i32* %arrayidx.i.i, align 4<br>
> +  %and.i.i = and i32 %7, 32768<br>
> +  br label %isupper.exit<br>
> +cond.false.i.i:<br>
> +  %8 = trunc i64 %idxprom.i.i to i8<br>
> +  %conv8 = sext i8 %8 to i32<br>
> +  %call3.i.i = tail call i32 @__maskrune(i32 %conv8, i64 32768) #3<br>
> +  br label %isupper.exit<br>
> +isupper.exit:<br>
> +  %tobool1.sink.i.in.i = phi i32 [ %and.i.i, %cond.true.i.i ], [ %call3.i.i, %cond.false.i.i ]<br>
> +  %tobool1.sink.i.i = icmp eq i32 %tobool1.sink.i.in.i, 0<br>
> +  br i1 %tobool1.sink.i.i, label %lor.rhs, label %while.body, !prof !989<br>
> +lor.rhs:<br>
> +  %sunkaddr = ptrtoint i8* %5 to i64<br>
> +  %sunkaddr58 = add i64 %sunkaddr, %lsr.iv27<br>
> +  %sunkaddr59 = inttoptr i64 %sunkaddr58 to i8*<br>
> +  %9 = load i8* %sunkaddr59, align 1<br>
> +  %idxprom.i.i214 = sext i8 %9 to i64<br>
> +  %isascii.i.i213225 = icmp sgt i8 %9, -1<br>
> +  br i1 %isascii.i.i213225, label %cond.true.i.i217, label %cond.false.i.i219, !prof !181<br>
> +cond.true.i.i217:<br>
> +  %arrayidx.i.i215 = getelementptr inbounds %struct._RuneLocale* @_DefaultRuneLocale, i64 0, i32 5, i64 %idxprom.i.i214<br>
> +  %10 = load i32* %arrayidx.i.i215, align 4<br>
> +  %and.i.i216 = and i32 %10, 32768<br>
> +  br label %isupper.exit223<br>
> +cond.false.i.i219:<br>
> +  %11 = trunc i64 %idxprom.i.i214 to i8<br>
> +  %conv9 = sext i8 %11 to i32<br>
> +  %call3.i.i218 = tail call i32 @__maskrune(i32 %conv9, i64 32768) #3<br>
> +  br label %isupper.exit223<br>
> +isupper.exit223:<br>
> +  %tobool1.sink.i.in.i220 = phi i32 [ %and.i.i216, %cond.true.i.i217 ], [ %call3.i.i218, %cond.false.i.i219 ]<br>
> +  %tobool1.sink.i.i221 = icmp eq i32 %tobool1.sink.i.in.i220, 0<br>
> +  br i1 %tobool1.sink.i.i221, label %while.end, label %while.body, !prof !990<br>
> +while.body:<br>
> +  %sunkaddr60 = ptrtoint i8* %4 to i64<br>
> +  %sunkaddr61 = add i64 %sunkaddr60, %lsr.iv27<br>
> +  %sunkaddr62 = inttoptr i64 %sunkaddr61 to i8*<br>
> +  %12 = load i8* %sunkaddr62, align 1<br>
> +  %sunkaddr63 = ptrtoint i8* %5 to i64<br>
> +  %sunkaddr64 = add i64 %sunkaddr63, %lsr.iv27<br>
> +  %sunkaddr65 = inttoptr i64 %sunkaddr64 to i8*<br>
> +  %13 = load i8* %sunkaddr65, align 1<br>
> +  %cmp14 = icmp eq i8 %12, %13<br>
> +  br i1 %cmp14, label %if.end17, label %return, !prof !991<br>
> +if.end17:<br>
> +  %lsr.iv.next28 = add i64 %lsr.iv27, 1<br>
> +  br label %while.cond<br>
> +while.end:<br>
> +  %14 = or i8 %3, %2<br>
> +  %15 = icmp eq i8 %14, 0<br>
> +  br i1 %15, label %if.then23, label %if.else88, !prof !992<br>
> +if.then23:<br>
> +  %sunkaddr66 = ptrtoint %struct.Connector_struct* %a to i64<br>
> +  %sunkaddr67 = add i64 %sunkaddr66, 16<br>
> +  %sunkaddr68 = inttoptr i64 %sunkaddr67 to i8**<br>
> +  %16 = load i8** %sunkaddr68, align 8<br>
> +  %17 = load i8* %16, align 1<br>
> +  %cmp26 = icmp eq i8 %17, 83<br>
> +  %sunkaddr69 = ptrtoint i8* %4 to i64<br>
> +  %sunkaddr70 = add i64 %sunkaddr69, %lsr.iv27<br>
> +  %sunkaddr71 = inttoptr i64 %sunkaddr70 to i8*<br>
> +  %18 = load i8* %sunkaddr71, align 1<br>
> +  br i1 %cmp26, label %land.lhs.true28, label %while.cond59.preheader, !prof !993<br>
> +land.lhs.true28:<br>
> +  switch i8 %18, label %land.rhs.preheader [<br>
> +    i8 112, label %land.lhs.true35<br>
> +    i8 0, label %return<br>
> +  ], !prof !994<br>
> +land.lhs.true35:<br>
> +  %sunkaddr72 = ptrtoint i8* %5 to i64<br>
> +  %sunkaddr73 = add i64 %sunkaddr72, %lsr.iv27<br>
> +  %sunkaddr74 = inttoptr i64 %sunkaddr73 to i8*<br>
> +  %19 = load i8* %sunkaddr74, align 1<br>
> +  switch i8 %19, label %land.rhs.preheader [<br>
> +    i8 112, label %land.lhs.true43<br>
> +  ], !prof !995<br>
> +land.lhs.true43:<br>
> +  %20 = ptrtoint i8* %16 to i64<br>
> +  %21 = sub i64 0, %20<br>
> +  %scevgep52 = getelementptr i8* %4, i64 %21<br>
> +  %scevgep53 = getelementptr i8* %scevgep52, i64 %lsr.iv27<br>
> +  %scevgep54 = getelementptr i8* %scevgep53, i64 -1<br>
> +  %cmp45 = icmp eq i8* %scevgep54, null<br>
> +  br i1 %cmp45, label %return, label %lor.lhs.false47, !prof !996<br>
> +lor.lhs.false47:<br>
> +  %22 = ptrtoint i8* %16 to i64<br>
> +  %23 = sub i64 0, %22<br>
> +  %scevgep47 = getelementptr i8* %4, i64 %23<br>
> +  %scevgep48 = getelementptr i8* %scevgep47, i64 %lsr.iv27<br>
> +  %scevgep49 = getelementptr i8* %scevgep48, i64 -2<br>
> +  %cmp50 = icmp eq i8* %scevgep49, null<br>
> +  br i1 %cmp50, label %land.lhs.true52, label %while.cond59.preheader, !prof !997<br>
> +land.lhs.true52:<br>
> +  %sunkaddr75 = ptrtoint i8* %4 to i64<br>
> +  %sunkaddr76 = add i64 %sunkaddr75, %lsr.iv27<br>
> +  %sunkaddr77 = add i64 %sunkaddr76, -1<br>
> +  %sunkaddr78 = inttoptr i64 %sunkaddr77 to i8*<br>
> +  %24 = load i8* %sunkaddr78, align 1<br>
> +  %cmp55 = icmp eq i8 %24, 73<br>
> +  %cmp61233 = icmp eq i8 %18, 0<br>
> +  %or.cond265 = or i1 %cmp55, %cmp61233<br>
> +  br i1 %or.cond265, label %return, label %land.rhs.preheader, !prof !998<br>
> +while.cond59.preheader:<br>
> +  %cmp61233.old = icmp eq i8 %18, 0<br>
> +  br i1 %cmp61233.old, label %return, label %land.rhs.preheader, !prof !999<br>
> +land.rhs.preheader:<br>
> +  %scevgep33 = getelementptr i8* %5, i64 %lsr.iv27<br>
> +  %scevgep43 = getelementptr i8* %4, i64 %lsr.iv27<br>
> +  br label %land.rhs<br>
> +land.rhs:<br>
> +  %lsr.iv = phi i64 [ 0, %land.rhs.preheader ], [ %lsr.iv.next, %if.then83 ]<br>
> +  %25 = phi i8 [ %27, %if.then83 ], [ %18, %land.rhs.preheader ]<br>
> +  %scevgep34 = getelementptr i8* %scevgep33, i64 %lsr.iv<br>
> +  %26 = load i8* %scevgep34, align 1<br>
> +  %cmp64 = icmp eq i8 %26, 0<br>
> +  br i1 %cmp64, label %return, label %while.body66, !prof !1000<br>
> +while.body66:<br>
> +  %cmp68 = icmp eq i8 %25, 42<br>
> +  %cmp72 = icmp eq i8 %26, 42<br>
> +  %or.cond = or i1 %cmp68, %cmp72<br>
> +  br i1 %or.cond, label %if.then83, label %lor.lhs.false74, !prof !1001<br>
> +lor.lhs.false74:<br>
> +  %cmp77 = icmp ne i8 %25, %26<br>
> +  %cmp81 = icmp eq i8 %25, 94<br>
> +  %or.cond208 = or i1 %cmp77, %cmp81<br>
> +  br i1 %or.cond208, label %return, label %if.then83, !prof !1002<br>
> +if.then83:<br>
> +  %scevgep44 = getelementptr i8* %scevgep43, i64 %lsr.iv<br>
> +  %scevgep45 = getelementptr i8* %scevgep44, i64 1<br>
> +  %27 = load i8* %scevgep45, align 1<br>
> +  %cmp61 = icmp eq i8 %27, 0<br>
> +  %lsr.iv.next = add i64 %lsr.iv, 1<br>
> +  br i1 %cmp61, label %return, label %land.rhs, !prof !999<br>
> +if.else88:<br>
> +  %cmp89 = icmp eq i8 %2, 1<br>
> +  %cmp92 = icmp eq i8 %3, 2<br>
> +  %or.cond159 = and i1 %cmp89, %cmp92<br>
> +  br i1 %or.cond159, label %while.cond95.preheader, label %if.else123, !prof !1003<br>
> +while.cond95.preheader:<br>
> +  %sunkaddr79 = ptrtoint i8* %4 to i64<br>
> +  %sunkaddr80 = add i64 %sunkaddr79, %lsr.iv27<br>
> +  %sunkaddr81 = inttoptr i64 %sunkaddr80 to i8*<br>
> +  %28 = load i8* %sunkaddr81, align 1<br>
> +  %cmp97238 = icmp eq i8 %28, 0<br>
> +  br i1 %cmp97238, label %return, label %land.rhs99.preheader, !prof !1004<br>
> +land.rhs99.preheader:<br>
> +  %scevgep31 = getelementptr i8* %5, i64 %lsr.iv27<br>
> +  %scevgep40 = getelementptr i8* %4, i64 %lsr.iv27<br>
> +  br label %land.rhs99<br>
> +land.rhs99:<br>
> +  %lsr.iv17 = phi i64 [ 0, %land.rhs99.preheader ], [ %lsr.iv.next18, %if.then117 ]<br>
> +  %29 = phi i8 [ %31, %if.then117 ], [ %28, %land.rhs99.preheader ]<br>
> +  %scevgep32 = getelementptr i8* %scevgep31, i64 %lsr.iv17<br>
> +  %30 = load i8* %scevgep32, align 1<br>
> +  %cmp101 = icmp eq i8 %30, 0<br>
> +  br i1 %cmp101, label %return, label %while.body104, !prof !1005<br>
> +while.body104:<br>
> +  %cmp107 = icmp eq i8 %29, %30<br>
> +  %cmp111 = icmp eq i8 %29, 42<br>
> +  %or.cond209 = or i1 %cmp107, %cmp111<br>
> +  %cmp115 = icmp eq i8 %30, 94<br>
> +  %or.cond210 = or i1 %or.cond209, %cmp115<br>
> +  br i1 %or.cond210, label %if.then117, label %return, !prof !1006<br>
> +if.then117:<br>
> +  %scevgep41 = getelementptr i8* %scevgep40, i64 %lsr.iv17<br>
> +  %scevgep42 = getelementptr i8* %scevgep41, i64 1<br>
> +  %31 = load i8* %scevgep42, align 1<br>
> +  %cmp97 = icmp eq i8 %31, 0<br>
> +  %lsr.iv.next18 = add i64 %lsr.iv17, 1<br>
> +  br i1 %cmp97, label %return, label %land.rhs99, !prof !1004<br>
> +if.else123:<br>
> +  %cmp124 = icmp eq i8 %3, 1<br>
> +  %cmp127 = icmp eq i8 %2, 2<br>
> +  %or.cond160 = and i1 %cmp124, %cmp127<br>
> +  br i1 %or.cond160, label %while.cond130.preheader, label %return, !prof !1007<br>
> +while.cond130.preheader:<br>
> +  %sunkaddr82 = ptrtoint i8* %4 to i64<br>
> +  %sunkaddr83 = add i64 %sunkaddr82, %lsr.iv27<br>
> +  %sunkaddr84 = inttoptr i64 %sunkaddr83 to i8*<br>
> +  %32 = load i8* %sunkaddr84, align 1<br>
> +  %cmp132244 = icmp eq i8 %32, 0<br>
> +  br i1 %cmp132244, label %return, label %land.rhs134.preheader, !prof !1008<br>
> +land.rhs134.preheader:<br>
> +  %scevgep29 = getelementptr i8* %5, i64 %lsr.iv27<br>
> +  %scevgep37 = getelementptr i8* %4, i64 %lsr.iv27<br>
> +  br label %land.rhs134<br>
> +land.rhs134:<br>
> +  %lsr.iv22 = phi i64 [ 0, %land.rhs134.preheader ], [ %lsr.iv.next23, %if.then152 ]<br>
> +  %33 = phi i8 [ %35, %if.then152 ], [ %32, %land.rhs134.preheader ]<br>
> +  %scevgep30 = getelementptr i8* %scevgep29, i64 %lsr.iv22<br>
> +  %34 = load i8* %scevgep30, align 1<br>
> +  %cmp136 = icmp eq i8 %34, 0<br>
> +  br i1 %cmp136, label %return, label %while.body139, !prof !1009<br>
> +while.body139:<br>
> +  %cmp142 = icmp eq i8 %33, %34<br>
> +  %cmp146 = icmp eq i8 %34, 42<br>
> +  %or.cond211 = or i1 %cmp142, %cmp146<br>
> +  %cmp150 = icmp eq i8 %33, 94<br>
> +  %or.cond212 = or i1 %or.cond211, %cmp150<br>
> +  br i1 %or.cond212, label %if.then152, label %return, !prof !1010<br>
> +if.then152:<br>
> +  %scevgep38 = getelementptr i8* %scevgep37, i64 %lsr.iv22<br>
> +  %scevgep39 = getelementptr i8* %scevgep38, i64 1<br>
> +  %35 = load i8* %scevgep39, align 1<br>
> +  %cmp132 = icmp eq i8 %35, 0<br>
> +  %lsr.iv.next23 = add i64 %lsr.iv22, 1<br>
> +  br i1 %cmp132, label %return, label %land.rhs134, !prof !1008<br>
> +return:<br>
> +  %retval.0 = phi i32 [ 0, %entry ], [ 1, %land.lhs.true52 ], [ 1, %land.lhs.true43 ], [ 0, %if.else123 ], [ 1, %while.cond59.preheader ], [ 1, %while.cond95.preheader ], [ 1, %while.cond130.preheader ], [ 1, %land.lhs.true28 ], [ 1, %if.then83 ], [ 0, %lor.lhs.false74 ], [ 1, %land.rhs ], [ 1, %if.then117 ], [ 0, %while.body104 ], [ 1, %land.rhs99 ], [ 1, %if.then152 ], [ 0, %while.body139 ], [ 1, %land.rhs134 ], [ 0, %while.body ]<br>

> +  ret i32 %retval.0<br>
> +}<br>
> +!181 = metadata !{metadata !"branch_weights", i32 662038, i32 1}<br>
> +!988 = metadata !{metadata !"branch_weights", i32 12091450, i32 1916}<br>
> +!989 = metadata !{metadata !"branch_weights", i32 7564670, i32 4526781}<br>
> +!990 = metadata !{metadata !"branch_weights", i32 7484958, i32 13283499}<br>
> +!991 = metadata !{metadata !"branch_weights", i32 8677007, i32 4606493}<br>
> +!992 = metadata !{metadata !"branch_weights", i32 -1172426948, i32 145094705}<br>
> +!993 = metadata !{metadata !"branch_weights", i32 1468914, i32 5683688}<br>
> +!994 = metadata !{metadata !"branch_weights", i32 114025221, i32 -1217548794, i32 -1199521551, i32 87712616}<br>
> +!995 = metadata !{metadata !"branch_weights", i32 1853716452, i32 -444717951, i32 932776759}<br>
> +!996 = metadata !{metadata !"branch_weights", i32 1004870, i32 20259}<br>
> +!997 = metadata !{metadata !"branch_weights", i32 20071, i32 189}<br>
> +!998 = metadata !{metadata !"branch_weights", i32 -1020255939, i32 572177766}<br>
> +!999 = metadata !{metadata !"branch_weights", i32 2666513, i32 3466431}<br>
> +!1000 = metadata !{metadata !"branch_weights", i32 5117635, i32 1859780}<br>
> +!1001 = metadata !{metadata !"branch_weights", i32 354902465, i32 -1444604407}<br>
> +!1002 = metadata !{metadata !"branch_weights", i32 -1762419279, i32 1592770684}<br>
> +!1003 = metadata !{metadata !"branch_weights", i32 1435905930, i32 -1951930624}<br>
> +!1004 = metadata !{metadata !"branch_weights", i32 1, i32 504888}<br>
> +!1005 = metadata !{metadata !"branch_weights", i32 94662, i32 504888}<br>
> +!1006 = metadata !{metadata !"branch_weights", i32 -1897793104, i32 160196332}<br>
> +!1007 = metadata !{metadata !"branch_weights", i32 2074643678, i32 -29579071}<br>
> +!1008 = metadata !{metadata !"branch_weights", i32 1, i32 226163}<br>
> +!1009 = metadata !{metadata !"branch_weights", i32 58357, i32 226163}<br>
> +!1010 = metadata !{metadata !"branch_weights", i32 -2072848646, i32 92907517}<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
</div></div></blockquote></div><br></div></div>