OSDN Git Service

2010-12-01 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Dec 2010 13:13:23 +0000 (13:13 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Dec 2010 13:13:23 +0000 (13:13 +0000)
PR tree-optimization/46730
* value-prof.c (gimple_ic): Always generate a separate merge BB.

* g++.dg/tree-prof/indir-call-prof-2.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167326 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-prof/indir-call-prof-2.C [new file with mode: 0644]
gcc/value-prof.c

index 735cde3..56bb534 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/46730
+       * value-prof.c (gimple_ic): Always generate a separate merge BB.
+
 2010-11-30  Ian Lance Taylor  <iant@google.com>
 
        * config/i386/linux.h (ASM_SPEC): Pass -v as -v, not -V.  Remove
index 1514fd0..55f33a1 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-01  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/46730
+       * g++.dg/tree-prof/indir-call-prof-2.C: New testcase.
+
 2010-11-30  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/ppc-fma-7.c: New file, test that (a*b)+c and
diff --git a/gcc/testsuite/g++.dg/tree-prof/indir-call-prof-2.C b/gcc/testsuite/g++.dg/tree-prof/indir-call-prof-2.C
new file mode 100644 (file)
index 0000000..e20cc64
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-options "-O" } */
+
+int foo1(void) { return 0; }
+int bar1(void) { throw 1; }
+void foo2(void) { }
+void bar2(void) { throw 1; }
+void __attribute__((noinline,noclone)) test1(void (*f)(void)) { (*f)(); }
+void __attribute__((noinline,noclone)) test2(void (*f)(void)) { (*f)(); }
+int __attribute__((noinline,noclone)) test3(int (*f)(void)) { return (*f)(); }
+int __attribute__((noinline,noclone)) test4(int (*f)(void)) { return (*f)(); }
+int __attribute__((noinline,noclone)) test5(int (*f)(void), int x) { return x ? x : (*f)(); }
+int __attribute__((noinline,noclone)) test6(int (*f)(void), int x) { return x ? x : (*f)(); }
+void __attribute__((noinline,noclone)) test7(void (*f)(void)) { try { (*f)(); } catch (...) {} }
+void __attribute__((noinline,noclone)) test8(void (*f)(void)) { try { (*f)();  } catch (...) {}}
+int __attribute__((noinline,noclone)) test9(int (*f)(void)) { try { return (*f)(); } catch (...) {return 0;} }
+int __attribute__((noinline,noclone)) test10(int (*f)(void)) { try { return (*f)(); } catch (...) {return 0;} }
+int __attribute__((noinline,noclone)) test11(int (*f)(void), int x) { try { return x ? x : (*f)(); } catch (...) {return 0;} }
+int __attribute__((noinline,noclone)) test12(int (*f)(void), int x) { try { return x ? x : (*f)(); } catch (...) {return 0;} }
+
+int main()
+{
+  for (int i = 0; i < 100; ++i) test1(foo2);
+  for (int i = 0; i < 100; ++i) try { test2(bar2); } catch (...) {} 
+  for (int i = 0; i < 100; ++i) test3(foo1);
+  for (int i = 0; i < 100; ++i) try { test4(bar1); } catch (...) {} 
+  for (int i = 0; i < 100; ++i) test5(foo1, 0);
+  for (int i = 0; i < 100; ++i) try { test6(bar1, 0); } catch (...) {} 
+  for (int i = 0; i < 100; ++i) test7(foo2);
+  for (int i = 0; i < 100; ++i) try { test8(bar2); } catch (...) {} 
+  for (int i = 0; i < 100; ++i) test9(foo1);
+  for (int i = 0; i < 100; ++i) try { test10(bar1); } catch (...) {} 
+  for (int i = 0; i < 100; ++i) test11(foo1, 0);
+  for (int i = 0; i < 100; ++i) try { test12(bar1, 0); } catch (...) {} 
+  return 0;
+}
index 9e27a96..6011922 100644 (file)
@@ -1146,10 +1146,15 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
   icall_bb->count = all - count;
 
   /* Do not disturb existing EH edges from the indirect call.  */
-  if (last_stmt (icall_bb) != icall_stmt)
+  if (gsi_stmt (gsi_last_bb (icall_bb)) != icall_stmt)
     e_ij = split_block (icall_bb, icall_stmt);
   else
-    e_ij = find_fallthru_edge (icall_bb->succs);
+    {
+      e_ij = find_fallthru_edge (icall_bb->succs);
+      e_ij->probability = REG_BR_PROB_BASE;
+      e_ij->count = all - count;
+      e_ij = single_pred_edge (split_edge (e_ij));
+    }
   join_bb = e_ij->dest;
   join_bb->count = all;