From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12721 invoked by alias); 2 May 2014 10:52:54 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 12182 invoked by uid 48); 2 May 2014 10:52:49 -0000 From: "glisse at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/61034] New: Optimizing takes too many passes Date: Fri, 02 May 2014 10:52:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: 4.10.0 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: normal X-Bugzilla-Who: glisse at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status keywords bug_severity priority component assigned_to reporter Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-05/txt/msg00066.txt.bz2 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; }