[PATCH] D18827: Rework/enhance stack coloring data flow analysis.

Wei Mi via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 09:37:20 PDT 2016


Than,

Thank you for the detailed explanation of the implementation difference
between GCC and LLVM. I have a question about GCC's implementation inlined.

On Mon, Apr 11, 2016 at 8:15 AM, Than McIntosh <thanm at google.com> wrote:

> thanm added a comment.
>
> Hi Wei,
>
> Thanks for the review. I responded to your comments in line.
>
> You are quite right, even after this patch, clang/llvm will still worse
> than GCC.  The reason has to do with the way that the GCC code computes
> interferences between variables.
>
> The GCC implementation uses an interference graph (node == var, edge ==
> coloring conflict between vars), and it adds edges in the interference
> graph only at DEFs: statements where there could conceivably be some sort
> of memory write. In contrast, the LLVM algorithm works by building live
> intervals and checking to see whether there is any overlap between the
> intervals (there is no attention paid to DEF vs non-DEF). This second
> strategy is simpler but is definitely less precise in some cases.
>
> Let me expand on this a bit. Going back to the if/then example:
>
>   int foo(int x) {
>     int ar1[128]; int ar2[128];
>     if (x & 0x99) {
>       bar(&ar1); return x-1;
>     } else {
>       bar(&ar2); return x+1;
>     }
>   }
>
> Here is what the IR looks like at the point where the analysis is done
> (it's pretety much the same between both GCC and LLVM at an abstract level):
>
>          BB#1:
>   I0:    call bar(&ar1)
>   I1:    %vreg1 = %vregx - 1
>   I2:    jmp BB3
>
>          BB#2:
>   I3:    call bar(&ar1)
>   I4:    %vreg2 = %vregx + 1
>          <fall through>
>
>          BB#3:
>   I5:    %vrefr = phi(%vreg1, %vreg2)
>   I6:    LIFETIME_END <ar1>
>   I7:    LIFETIME_END <ar2>
>   I8:    <return %vregr>
>
> As mentioned previously, the GCC algorithm uses an uses an interference
> graph -- for each variable X it keeps a bit vector of other variables that
> X interferes with. At each BB, it computes the live-in set for the BB by
> unioning together the live out sets of the pred BBs. It then walks the BB
> and looks for any instruction that could write memory (essentially anything
> other than phi or debug). At such an inst, it adds conflicts between every
> variable in the work set.
>
> At the point where GCC processes BB#3 above, both "ar1" and "ar2" are in
> the work set. However as it walks through the BB it never sees any
> instruction that could write memory, so it never adds conflicts between the
> vars.
>
>
But isn't bar() could potentially change ar1 and ar2 indirectly since ar1
and ar2 are escaped local arrays from current func?


>
> Given that the new implementation is a bit better but not ideal, I think
> we can revisit it at some point and decide whether we want to throw out
> intervals and move to interference-graph.
>
>
Yes, I agree with you.

Thanks,
Wei.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160411/eb61909e/attachment.html>


More information about the llvm-commits mailing list