From patchwork Wed Jun 30 17:20:07 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 57442 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 3F9E8B6F01 for ; Thu, 1 Jul 2010 03:20:23 +1000 (EST) Received: (qmail 14712 invoked by alias); 30 Jun 2010 17:20:19 -0000 Received: (qmail 14696 invoked by uid 22791); 30 Jun 2010 17:20:17 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nikam-dmz.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 30 Jun 2010 17:20:09 +0000 Received: from localhost (occam.ms.mff.cuni.cz [195.113.18.121]) by nikam.ms.mff.cuni.cz (Postfix) with ESMTP id 18D999AC7EA; Wed, 30 Jun 2010 19:20:07 +0200 (CEST) Received: by localhost (Postfix, from userid 16202) id 12F8456415F; Wed, 30 Jun 2010 19:20:07 +0200 (CEST) Date: Wed, 30 Jun 2010 19:20:07 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, rguenther@suse.de Subject: PR middle-end/PR44706 II (wrong profile estimate) Message-ID: <20100630172006.GL6233@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, this patch fixes the other problem. In the testcase there is call to throw () that ends up predicted as likely. Noreturn call heruistic should make it predicted unlikely, but this does not happen. It looks for control dependence block of the call and predict edge as unlikely. However the block has only EH edge except for the one predicted so the prediction has no effect. This patch makes predict_paths_for_bb to check if there is another non-abnormal/fake/eh edge out of the BB that leads to block not postominated by BB and drops prediction only in that case. If this is not the case, it looks for control dependce of the new block until something is found. Bootstrapped/regtested x86_64-linux. Will hold the commit until after the merge unless Richard tells me it is fine otherwise. Honza PR middle-end/44706 * g++.dg/tree-ssa/pr44706.C: New testcase. * predict.c (predict_paths_for_bb): Handle case when control dependence BB has only abnormal edges. Index: testsuite/g++.dg/tree-ssa/pr44706.C =================================================================== --- testsuite/g++.dg/tree-ssa/pr44706.C (revision 0) +++ testsuite/g++.dg/tree-ssa/pr44706.C (revision 0) @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-fnsplit" } */ +class MemoryManager; +class XMLExcepts { +public : + enum Codes { + AttrList_BadIndex + }; +}; +class XMLException { +public: + XMLException(const char* const srcFile, const unsigned int srcLine, +MemoryManager* const memoryManager = 0); +}; +class ArrayIndexOutOfBoundsException : public XMLException { +public: + ArrayIndexOutOfBoundsException(const char* const srcFile , const unsigned +int srcLine , const XMLExcepts::Codes toThrow , MemoryManager* memoryManager = +0) : XMLException(srcFile, srcLine, memoryManager) { + } +}; +class XMLAttDef { + bool fExternalAttribute; +}; +class XMLAttDefList { +public: + MemoryManager* getMemoryManager() const; +}; +class DTDAttDef : public XMLAttDef { +}; +class DTDAttDefList : public XMLAttDefList { + virtual const XMLAttDef &getAttDef(unsigned int index) const ; + DTDAttDef** fArray; + unsigned int fCount; +}; +const XMLAttDef &DTDAttDefList::getAttDef(unsigned int index) const { + if(index >= fCount) + throw ArrayIndexOutOfBoundsException("foo.cpp", 0, +XMLExcepts::AttrList_BadIndex, getMemoryManager()); + return *(fArray[index]); +} + +/* Mistake in branch prediction caused us to split away real body of the function keeping + only throw () invokation. This is bad idea. */ +/* { dg-final { scan-tree-dump-not "Splitting function" "fnsplit"} } */ +/* { dg-final { cleanup-tree-dump "fnsplit" } } */ Index: predict.c =================================================================== --- predict.c (revision 161597) +++ predict.c (working copy) @@ -1786,8 +1786,33 @@ predict_paths_for_bb (basic_block cur, b if (e->src->index >= NUM_FIXED_BLOCKS && !dominated_by_p (CDI_POST_DOMINATORS, e->src, bb)) { + edge e2; + edge_iterator ei2; + bool found = false; + + /* Ignore abnormals, we predict them as not taken anyway. */ + if (e->flags & (EDGE_EH | EDGE_FAKE | EDGE_ABNORMAL)) + continue; gcc_assert (bb == cur || dominated_by_p (CDI_POST_DOMINATORS, cur, bb)); - predict_edge_def (e, pred, taken); + + /* See if there is how many edge from e->src that is not abnormal + and does not lead to BB. */ + FOR_EACH_EDGE (e2, ei2, e->src->succs) + if (e2 != e + && !(e2->flags & (EDGE_EH | EDGE_FAKE | EDGE_ABNORMAL)) + && !dominated_by_p (CDI_POST_DOMINATORS, e2->dest, bb)) + { + found = true; + break; + } + + /* If there is non-abnormal path leaving e->src, predict edge + using predictor. Otherwise we need to look for paths + leading to e->src. */ + if (found) + predict_edge_def (e, pred, taken); + else + predict_paths_for_bb (e->src, e->src, pred, taken); } for (son = first_dom_son (CDI_POST_DOMINATORS, cur); son;