I 've been looking at the problem of converting the struct-equiv code to
use DEF-USE chains
instead of global dataflow information, but I have hit a snag.
We can find local registers as being registers that are defined
somewhere in the examined (partial) block,
and have all their uses within the (partial) block. However, there is
no feasible way to find dying inputs
with def-use / use-def chains. We could find the definition with
use-def chains, and examine all the uses
of this definition with def-use chains, but we can't easily tell if a
use could be reached through the examined
(partial) block.
And this is really not an isolated problem. Generally, when we examine
REG_DEAD notes, there is no
equivalent information to be found in def-use chains. The problem is
that we are not really interested
in what uses can be reached from the definition, but which can be
reached from the use we are examining.
I.e. we'd like a list of uses of the same register after the current
use. In fact, we don't need an exhaustive list.
It is sufficient if we have a set of uses such that any use which is
reachable from the current use is dominated
by one of the uses in the set (a minimal set is desirable, but not
necessary). With these sets in place, we could
also restrict the def-use information to such a set. When we add back
pointers to each link, these data structures
should be reasonably easy to keep sufficiently up-to-date to remain
usable, i.e. such that every dependency is
represented, and that there are no dangling pointers.