[tree-ssa] copy propagation and the abstraction penalty
Joe Buck
jbuck@synopsys.com
Thu May 15 22:48:00 GMT 2003
On Thu, May 15, 2003 at 03:17:48PM -0700, Richard Henderson wrote:
> On Thu, May 15, 2003 at 10:10:22AM -0400, Diego Novillo wrote:
> > I'm also wondering if we could change the
> > may-alias between this and UV2150 to a must-alias, which would
> > completely free this program from aliasing problems:
>
> Indeed. And for this case I definitely think it's the right thing to do.
>
> IMO constant propagation should be able to take
>
> T.8_2 = &<UVa150>;
> {
> struct complex * const this;
>
> this_3 = (struct complex * const)T.8_2;
> {
> this->re = 1.0e+0;
>
> and turn it into
>
> (&<UVa150>)->re = 1.0e+0
>
> which folds to
>
> <UVa150>.re = 1.0e+0
>
> At which point we have no aliasing problem, and a subsequent round
> of constant propagation ought to be able to send 1.0e+0 to its
> destination.
That helps this case, but in many other cases the content of the temporary
struct's field will be a variable, and we would still want to copy-propagate.
For example, consider bit vector classes. Typically the [] operator will
be overloaded to return a "bitref" object, which is a struct that has two
fields: a reference to the bit vector, and a bit offset. The compiler
should be able to eliminate the temporary object. We would have
struct bitref;
class bitvec {
public:
void set_bit(unsigned pos, bool value);
bool get_bit(unsigned pos) const;
inline bitref operator[](unsigned pos);
};
struct bitref {
bitref(bitvec& o, unsigned p) : obj(o), pos(p) {}
bitvec& obj;
unsigned pos;
operator bool() const { return obj.get_bit(pos);}
void operator=(bool value) { obj.set_bit(pos, value);}
void operator=(const bitref& src) { obj.set_bit(pos, src);}
};
inline bitref bitvec::operator[](unsigned pos) { return bitref(*this, pos);}
and we want to compile
void assign(bitvec& dest, bitvec& src, unsigned i, unsigned j) {
dest[i] = src[j];
}
Ideally, we should be able to do copy propagation good enough to turn this
into
dest.set_bit(i, src.get_bit(j));
which means that we can kill the two generated bitref objects. Note,
though, that there are no constants. We have {&dest,i} and {&src,j}.
This kind of thing occurs throughout common C++ codes, and really kills us
on the Boost graph library.
More information about the Gcc
mailing list