From f1d5a92b03feb7cd1d83397a7e2bab6d1ea8dde6 Mon Sep 17 00:00:00 2001 From: hubicka Date: Fri, 2 Jul 2010 09:39:54 +0000 Subject: [PATCH] PR middle-end/44706 * predict.c (predict_paths_for_bb): Handle case when control dependence BB has only abnormal edges. * g++.dg/tree-ssa/pr44706.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161691 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 +++++ gcc/predict.c | 27 ++++++++++++++++++- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/g++.dg/tree-ssa/pr44706.C | 46 +++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr44706.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 365a719..2e208ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-07-02 Jan Hubicka + + PR middle-end/44706 + * predict.c (predict_paths_for_bb): Handle case when control dependence + BB has only abnormal edges. + 2010-07-02 Richard Guenther PR tree-optimization/44748 diff --git a/gcc/predict.c b/gcc/predict.c index 5d61140..15d573b 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -1786,8 +1786,33 @@ predict_paths_for_bb (basic_block cur, basic_block bb, 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d9c0a99..651d8b6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-07-02 Jan Hubicka + + * g++.dg/tree-ssa/pr44706.C: New testcase. + 2010-07-02 Richard Guenther PR tree-optimization/44748 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr44706.C b/gcc/testsuite/g++.dg/tree-ssa/pr44706.C new file mode 100644 index 0000000..39904d8 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr44706.C @@ -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" } } */ -- 2.7.4