This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR middle-end/PR44706 II (wrong profile estimate)


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]