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

login
register
mail settings
Submitter Jan Hubicka
Date June 30, 2010, 5:20 p.m.
Message ID <20100630172006.GL6233@kam.mff.cuni.cz>
Download mbox | patch
Permalink /patch/57442/
State New
Headers show

Comments

Jan Hubicka - June 30, 2010, 5:20 p.m.
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.
Richard Henderson - June 30, 2010, 5:23 p.m.
On 06/30/2010 10:20 AM, Jan Hubicka wrote:
> +      /* See if there is how many edge from e->src that is not abnormal
> +	 and does not lead to BB.  */

Fix up the grammar in this comment please?  It's far enough off
that I don't know how it should be read.


r~

Patch

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;