[Bug tree-optimization/61034] New: Optimizing takes too many passes
glisse at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri May 2 10:52:00 GMT 2014
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61034
Bug ID: 61034
Summary: Optimizing takes too many passes
Product: gcc
Version: 4.10.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: glisse at gcc dot gnu.org
Hello,
when I compile the code below (-O3), I have plenty of calls to malloc left. If
I make the final expression simpler, they disappear. If I add some more
fre/copy_prop/dse/dce passes, they eventually get optimized, but the number of
passes required seems to increase with the size of the expression, which
obviously doesn't scale. Cycling through the passes seems like an obvious way
to work around this. Otherwise, I don't really know which pass to blame this
on. Maybe FRE could do better, it leaves some:
_79 = _73;
_79->count = _81;
[things that don't alias, small if-then-else]
_86 = _73;
_87 = _86->count;
which PRE will handle later after other passes have cleaned it up a bit and
removed everything in the middle []. But it isn't at all obvious this is the
right place to improve things.
The code is a reference counted double. I was trying to optimize something more
complicated, but the simpler things have to come first...
#define assume(x) if(!(x))__builtin_unreachable()
inline void* operator new(__SIZE_TYPE__ n){ return __builtin_malloc(n); }
inline void operator delete(void *p) { __builtin_free(p); }
struct O {
double num;
int count;
};
struct I {
O *o;
I(double d = 0) : o (new O) { o->num = d; o->count = 1; }
I(I const&i) { assume(i.o->count >= 1); o = i.o; ++o->count; }
I& operator=(I const&i) { I(i).swap(*this); return *this; }
~I() { if (--o->count == 0) delete o; }
void swap(I& i) { O *tmp = o; o = i.o; i.o = tmp; }
I& operator*= (I const&i) {
if (o->count > 1) *this = I(o->num);
o->num *= i.o->num;
return *this;
}
I& operator-= (I const&i) {
if (o->count > 1) *this = I(o->num);
o->num -= i.o->num;
return *this;
}
};
inline I operator* (I a, I const&b) { return a *= b; }
inline I operator- (I a, I const&b) { return a -= b; }
inline bool operator< (I const&a, I const&b) { return a.o->num < b.o->num; }
bool f(I a, I b, I c, I d) {
return (a * d - b * c) * (a * b - c * d) < 42;
}
More information about the Gcc-bugs
mailing list