This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Disable tree-ssa DSE for now
On Wed, 2005-01-19 at 13:06 +0100, Steven Bosscher wrote:
>
> I have also tried a single DSE pass with the patch from my first mail
> applied[1].
Note the primary reason I haven't gone forward with pushing the
handling of V_MUST_DEF into tree-ssa-dse.c is because I didn't
think we were in an appropriate phase for that kind of change.
While Mark has recently relaxed the check-in requirements, I
would still hesitate to use that as an opportunity to install
this kind of an improvement.
It's also the case that we can see a mixture of V_MAY_DEF and
V_MUST_DEFs for the same virtual operand. I'm pretty sure
my code to add V_MUST_DEFs handling to tree-ssa-dse.c doesn't
handle that properly (it's not particularly hard, but getting it
wrong would be bad).
> [1] http://gcc.gnu.org/ml/gcc-patches/2005-01/msg01183/DSE_prune_num_immuses.diff.gz
Unfortunately, I don't see any rationale behind the change to prune the
immediate uses. It might make sense, then again, it might not. A
little verbage on why you think this is safe and advisable would be
useful.
In a separate email you questioned why we have to consider the
RHS of a V_MAY_DEF as a use. Consider:
1. In some cases the RHS of a V_MAY_DEF represents a real read
from memory. If you look in the operand code you'll find that
if a statement has a virtual use of an object as well as a
V_MAY_DEF of that object, we drop the VUSE since the V_MAY_DEF
carries the same information.
This is something we installed a long long time ago and it was
showing a noticable improvement in both memory utilization and
compile-time behavior.
2. If you do not consider the RHS of a V_MAY_DEF as a use, then
the DSE code would have to follow chains of V_MAY_DEFs to
determine if a particular memory location is ever read. Let's
slightly modify one of your sample codes from pr18880:
int x;
int
f1 (int i, int j, int k)
{
int *p = k ? &i : &j;
i = 3;
*p = 5;
x = j;
return i;
}
Which results in the following code:
f1 (i, j, k)
{
int * p;
int D.1125;
int j.1;
int * iftmp.0;
# BLOCK 0
# PRED: ENTRY [100.0%] (fallthru,exec)
if (k_2 != 0) goto <L2>; else goto <L4>;
# SUCC: 2 [67.0%] (true,exec) 1 [33.0%] (false,exec)
# BLOCK 1
# PRED: 0 [33.0%] (false,exec)
<L4>:;
# SUCC: 2 [100.0%] (fallthru)
# BLOCK 2
# PRED: 0 [67.0%] (true,exec) 1 [100.0%] (fallthru)
# p_1 = PHI <&i(0), &j(1)>;
<L2>:;
# i_5 = V_MUST_DEF <i_4>;
i = 3;
# i_14 = V_MAY_DEF <i_5>;
# j_15 = V_MAY_DEF <j_6>;
*p_1 = 5;
# VUSE <j_15>;
j.1_7 = j;
# x_9 = V_MUST_DEF <x_8>;
x = j.1_7;
# VUSE <i_14>;
D.1125_10 = i;
return D.1125_10;
# SUCC: EXIT [100.0%]
}
What's important to note here is that the store into "i" is no longer
dead. But to determine that you have to follow the chain of V_*_DEFs
for the virtual "i". ie, just because i_5 has no VUSE does not mean
the store into "i" is dead. Instead you have to see that i_5 is used
in the RHS of a V_MUST_DEF and follow the LHS of that V_MAY_DEF (i_14
in this example). We find that i_14 is used in a VUSE and thus
the store i = 3 is not dead.
This is further complicated by PHIs -- since you'd have to track
through them or pessimize when you encounter them.
Jeff