[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