<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Sep 18, 2013 at 10:14 AM, Shuxin Yang <span dir="ltr"><<a href="mailto:shuxin.llvm@gmail.com" target="_blank">shuxin.llvm@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi, Daniel:<br>
<br>
With the helper of Andy and Nadav, I manage to come up a much simpler fix.<br>
It no longer delete dead code on the fly, it just proceeds in the presence<br>
of dead code.<br>
<br>
It is no longer complex both in terms of concept and LOC. In terms of LOC,<br>
it add 157 LOC with plenty of comments. In concept, it is almost "no-brainer",<br>
so to speak :-). </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
How does this patch look to you?<br>
<br></blockquote><div>Looks good to me.</div><div><br></div><div>Thank you so much or working through this :)<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks<br>
Shxuin<br>
<br>
How it work<br>
=======================<br>
Here is baiscially how dead code are "ignored".<br>
<br>
1) When a dead branch target, say block B, is identified, all the<br>
blocks dominated by B is dead as well.<br>
2) The phis of those blocks in dominance-frontier(B) is updated such<br>
that the operands corresponding to dead predecessors are replaced<br>
by "UndefVal".<br>
<br>
Using lattice's jargon, the "UndefVal" is the "Top" in essence.<br>
Phi node like this "phi(v1 bb1, undef xx)" will be optimized into<br>
"v1" if v1 is constant, or v1 is an instruction which dominate this<br>
phi node.<br>
3) When analyzing the availability of a load L, all dead mem-ops which<br>
L depends on disguise as a load which evaluate exactly same value as L.<br>
4) The dead mem-ops will be materialized as "UndefVal" during code motion.<br>
<br>
example<br>
=======<br>
Consider the e.g slightly generalized from the original motivating eg.<br>
<br>
Fig 1<br>
------------------------------<u></u>-----------------------<br>
BB1 :<br>
= *p; // s1<br>
if (false) {<br>
BB-then-dead:<br>
puts("Shuxin is a pretty nice guy!lol"). // s2, alias with *p;<br>
} else {<br>
BB-else:<br>
...<br>
}<br>
<br>
BB-junk:<br>
another if-then-else construct.<br>
<br>
BB-last:<br>
= *p; // s3;<br>
------------------------------<u></u>-----------------------<br>
<br>
The load in S3 deps on s1 and s2; the later is dead. Now that s2 alias with s3,<br>
due to the limit the Ld-PRE, it gives up.<br>
<br>
The step-3) will modify the dep-info about s2 to disguise as a load<br>
producing the same value as s3, and hence enable the transformation.<br>
<br>
Fig 2:<br>
------------------<br>
BB1 :<br>
v1 = *p; // s1<br>
if (false) {<br>
BB-then-dead:<br>
puts("Shuxin is a pretty nice guy!lol"). // s2, alias with *p;<br>
} else {<br>
BB-else:<br>
...<br>
}<br>
<br>
BB-junk:<br>
v3 = phi(v1@BB-else, undef@BB-then-dead)<br>
another if-then-else construct.<br>
<br>
BB-last:<br>
= v3; // s3;<br>
------------------<br>
<br>
LD-PRE Limitation<br>
=================<br>
With a closer look of the original problem. I realize GVN fail to eliminate<br>
the redundant load due to the limit the of LD-PRE.<br>
<br>
A typical whatever-PRE would pick up the "observation point" at the place<br>
available and unavailble path just meet (in this case, it would be the entry<br>
of BB-junk). However, GVN LD-PRE choose the point right before the load in<br>
question. In this case, it would be the entry point of BB-last, from that<br>
point of view, the load is unavilable in all the incoming pred. Hence give up.<br>
<br>
That said, I don't want to blame GVN as choosing right "observation point"<br>
entails expensive data flow analysis. However, llvm users are pretty picky<br>
at compile time.<br>
<br>
The limitation of this approach<br>
==============================<u></u>=<br>
The limitation comes from the fact that we are not able to simplify<br>
"v2 = phi(v1, undef)" into v if v neither dominate this phi nor is<br>
constant. By it machinary, val-num(v2) != val-num(v1) and hence obscure<br>
some opportunities.<br>
<br>
<br>
</blockquote></div><br></div></div>