From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27772 invoked by alias); 26 Jan 2014 11:31:36 -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 27745 invoked by uid 48); 26 Jan 2014 11:31:31 -0000 From: "glisse at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug ipa/59948] New: Optimize std::function Date: Sun, 26 Jan 2014 11:31:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: ipa X-Bugzilla-Version: 4.9.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-01/txt/msg02695.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59948 Bug ID: 59948 Summary: Optimize std::function Product: gcc Version: 4.9.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: glisse at gcc dot gnu.org #include inline int f(int i){return i-1;} int m(){ std::function h=f; return h(1); } clang manages to optimize this to just: int m(){return 0;} However, g++ is stuck with a much longer code (comments inline): int m() () { void * D.29797; struct function h; bool (*) (union _Any_data &, const union _Any_data &, _Manager_operation) _8; bool (*) (union _Any_data &, const union _Any_data &, _Manager_operation) _9; int (*) (const union _Any_data &, int) _24; int _26; : MEM[(struct _Function_base *)&h]._M_manager = 0B; if (f != 0B) // Shouldn't we know that f!=0? It is defined just above. goto ; else goto ; : MEM[(int (*) (int) *)&h] = f; h._M_invoker = _M_invoke; h.D.26519._M_manager = _M_manager; if (_M_manager == 0B) // Same, shouldn't we know that _M_manager!=0? goto ; else goto ; : std::__throw_bad_function_call (); : _24 = h._M_invoker; // Why not _M_invoke directly, we can only arrive here from bb3 // and nothing can clobber h._M_invoker. Then we might have a chance // to inline the next line. _26 = _24 (&h.D.26519._M_functor, 1); : _8 = MEM[(struct _Function_base *)&h]._M_manager; // I guess we need to fix the call to _24 above to know // there is nothing clobbering h._M_manager. if (_8 != 0B) goto ; else goto ; : _8 (&MEM[(struct _Function_base *)&h]._M_functor, &MEM[(struct _Function_base *)&h]._M_functor, 3); : h ={v} {CLOBBER}; h ={v} {CLOBBER}; return _26; : _9 = MEM[(struct _Function_base *)&h]._M_manager; if (_9 != 0B) goto ; else goto ; : _9 (&MEM[(struct _Function_base *)&h]._M_functor, &MEM[(struct _Function_base *)&h]._M_functor, 3); : h ={v} {CLOBBER}; _10 = __builtin_eh_pointer (2); __builtin_unwind_resume (_10); } Trying to modify std::function by removing tests, compiling with -fno-exceptions, etc, I got to situations with f(1) (not inlined), or we still had an uninlined call to _M_manager (which, inlined, would reduce to nothing), but never a clean return 0. If this simple example gets fixed, please check on the example in http://gcc.gnu.org/ml/gcc/2014-01/msg00261.html Related issues: PR 45631 PR 45632 PR 47413 (PR 56551)