This patch added regression tests for LIPO in google/main and fixes a couple of 
bugs found
in app testing:

1) duplicate assembler labels in .s file
2) missing icall profling for static functions indirect called
3) assertion in type 'merging'
4) gcov-dump bug.

Bootstrap compiler, regression test, and SPEC06 LIPO build.

Will commit to google/main.

Thanks,

David

2011-04-28  David Li  <davi...@google.com>

        * testsuite/gcc.dg/tree-prof/lipo/inliner-1.c   (revision 0): New test.
        * testsuite/gcc.dg/tree-prof/lipo/gdb_cmd       (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/bb-reorg.c    (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/stringop-1.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/pr34999.c     (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/stringop-2.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/update-loopch.c       (revision 0):
        * 
testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.040i.tree_profile_ipa       
(revision 0):
        Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1.c (revision 0): 
Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/update-tailcall.c     (revision 0): 
Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1a.c        
(revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/lipo.exp      (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/tracer-1.c    (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.145t.optimized      
(revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c     (revision 0): 
Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/val-prof-1.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/wcoverage-mismatch.c  (revision 0): 
Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/val-prof-2.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/pr45354.c     (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/val-prof-3.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/val-prof-4.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/val-prof-5.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/val-prof-6.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/val-prof-7.c  (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/pr47187.c     (revision 0): Ditto.
        * testsuite/gcc.dg/tree-prof/lipo/update-cunroll-2.c    (revision 0): 
Ditto.
        * testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args.C        
(revision 0): Ditto.
        * testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2.C   (revision 0): 
Ditto.
        * testsuite/g++.dg/tree-prof/lipo/indir-call-prof.C     (revision 0): 
Ditto.
        * testsuite/g++.dg/tree-prof/lipo/partition1.C  (revision 0): Ditto.
        * testsuite/g++.dg/tree-prof/lipo/partition2.C  (revision 0): Ditto.
        * testsuite/g++.dg/tree-prof/lipo/partition3.C  (revision 0): Ditto.
        * testsuite/g++.dg/tree-prof/lipo/lipo.exp      (revision 0): Ditto.
        * final.c       (revision 173136) (profile_function): Use FUNC_LABEL_ID.
        * dwarf2out.c   (revision 173136) (dwarf2out_vms_end_prologue): Ditto.
        (dwarf2out_vms_begin_epilogue): Ditto.
        (dwarf2out_vms_debug_main_pointer): Ditto.
        * cgraphunit.c  (revision 173136) (cgraph_finalize_compilation_unit):
        Remove eq type alias set computation.
        * tree-profile.c        (revision 173136) (gimple_gen_ic_func_profiler):
        (gimple_gen_ic_func_topn_profiler): Do not skip any functions.
        (tree_profiling): Add type alias merging.
        * l-ipo.c       (revision 173136) (restore_post_parsing_states): Use
        max funcdef_no.
        (pop_module_scope): Use max funcdef_no.
        * gcov-dump.c   (revision 173136) (tag_function): Fix a bug in function
        read.

Index: final.c
===================================================================
--- final.c     (revision 173136)
+++ final.c     (working copy)
@@ -1623,7 +1623,7 @@ profile_function (FILE *file ATTRIBUTE_U
       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
       switch_to_section (data_section);
       ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
-      targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
+      targetm.asm_out.internal_label (file, "LP", FUNC_LABEL_ID (cfun));
       assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
     }
 
@@ -1636,7 +1636,7 @@ profile_function (FILE *file ATTRIBUTE_U
     ASM_OUTPUT_REG_PUSH (file, REGNO (chain));
 #endif
 
-  FUNCTION_PROFILER (file, current_function_funcdef_no);
+  FUNCTION_PROFILER (file, FUNC_LABEL_ID (cfun));
 
 #ifdef ASM_OUTPUT_REG_PUSH
   if (chain && REG_P (chain))
Index: cgraphunit.c
===================================================================
--- cgraphunit.c        (revision 173136)
+++ cgraphunit.c        (working copy)
@@ -1117,11 +1117,6 @@ cgraph_finalize_compilation_unit (void)
   /* Gimplify and lower thunks.  */
   cgraph_analyze_functions ();
 
-  /* LIPO support  */
-  /* Recognize equivalent types across modules and
-     merge their alias sets.  */
-  cgraph_unify_type_alias_sets ();
-
   /* Finally drive the pass manager.  */
   cgraph_optimize ();
 
Index: testsuite/gcc.dg/tree-prof/lipo/inliner-1.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/inliner-1.c (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/inliner-1.c (revision 0)
@@ -0,0 +1,42 @@
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+int a;
+int b[100];
+void abort (void);
+
+inline void
+cold_function ()
+{
+  int i;
+  for (i = 0; i < 99; i++)
+    if (b[i] / (b[i+1] + 1))
+      abort ();
+}
+
+inline void
+hot_function ()
+{
+  int i;
+  for (i = 0; i < 99; i++)
+    if (b[i] / (b[i+1] + 1))
+      abort ();
+}
+
+main ()
+{
+  int i;
+  for (i = 0; i < 100; i++)
+    {
+      if (a)
+        cold_function ();
+      else
+        hot_function ();
+    }
+  return 0;
+}
+
+/* cold function should be inlined, while hot function should not.  
+   Look for "cold_function () [tail call];" call statement not for the
+   declaration or other apperances of the string in dump.  */
+/* { dg-final-use { scan-tree-dump "cold_function ..;" "optimized"} } */
+/* { dg-final-use { scan-tree-dump-not "hot_function ..;" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/gdb_cmd
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/gdb_cmd     (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/gdb_cmd     (revision 0)
@@ -0,0 +1,5 @@
+file 
/usr/local/google/davidxl/dev/gcc/gcc-gmain-native_64-linux/libexec/gcc/x86_64-linux/4.6.0-google-main/cc1
+set args -quiet -v indir-call-prof.c -march=core2 -mcx16 -msahf --param 
l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=4096 
-mtune=core2 -quiet -dumpbase indir-call-prof.c -auxbase indir-call-prof -g -O2 
-version -fprofile-generate -fripa -fdump-ipa-tree_profile_ipa 
-fdump-tree-optimized-blocks -o /tmp/ccdBoNgb.s
+b  main
+b internal_error
+b fancy_abort
Index: testsuite/gcc.dg/tree-prof/lipo/bb-reorg.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/bb-reorg.c  (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/bb-reorg.c  (revision 0)
@@ -0,0 +1,39 @@
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -freorder-blocks-and-partition" } */
+
+#include <string.h>
+
+#define SIZE 1000
+int t0 = 0;
+const char *t2[SIZE];
+char buf[SIZE];
+
+void
+foo (void)
+{
+  char *s = buf;
+  t0 = 1;
+
+  for (;;)
+    {
+      if (*s == '\0')
+       break;
+      else
+       {
+         t2[t0] = s;
+         t0++;
+       }
+      *s++ = '\0';
+    }
+  t2[t0] = NULL;
+}
+
+
+int
+main ()
+{
+  strcpy (buf, "hello");
+  foo ();
+  return 0; 
+}
+
Index: testsuite/gcc.dg/tree-prof/lipo/stringop-1.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/stringop-1.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/stringop-1.c        (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+int a[1000];
+int b[1000];
+int size=1;
+int max=10000;
+main()
+{
+  int i;
+  for (i=0;i<max; i++)
+    {
+      __builtin_memcpy (a, b, size * sizeof (a[0]));
+      asm("");
+    }
+   return 0;
+}
+/* { dg-final-use { scan-ipa-dump "Single value 4 stringop" 
"tree_profile_ipa"} } */
+/* Really this ought to simplify into assignment, but we are not there yet.  */
+/* a[0] = b[0] is what we fold the resulting memcpy into.  */
+/* { dg-final-use { scan-tree-dump " = MEM.*&b" "optimized"} } */
+/* { dg-final-use { scan-tree-dump "MEM.*&a\\\] = " "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/pr34999.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/pr34999.c   (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/pr34999.c   (revision 0)
@@ -0,0 +1,45 @@
+/* Same test as built-in-setjmp.c.  Includes the case where
+   the source block of a crossing fallthru edge ends with a call.  */
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -freorder-blocks-and-partition" } */
+
+extern int strcmp(const char *, const char *);
+extern char *strcpy(char *, const char *);
+extern void abort(void);
+extern void exit(int);
+
+void *buf[20];
+
+void __attribute__((noinline))
+sub2 (void)
+{
+  __builtin_longjmp (buf, 1);
+}
+
+int
+main ()
+{
+  char *p = (char *) __builtin_alloca (20);
+
+  strcpy (p, "test");
+
+  if (__builtin_setjmp (buf))
+    {
+      if (strcmp (p, "test") != 0)
+       abort ();
+
+      exit (0);
+    }
+
+  {
+    int *q = (int *) __builtin_alloca (p[2] * sizeof (int));
+    int i;
+    
+    for (i = 0; i < p[2]; i++)
+      q[i] = 0;
+
+    while (1)
+      sub2 ();
+  }
+}
+
Index: testsuite/gcc.dg/tree-prof/lipo/stringop-2.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/stringop-2.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/stringop-2.c        (revision 0)
@@ -0,0 +1,20 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+int a[1000];
+int b[1000];
+int size=1;
+int max=10000;
+main()
+{
+  int i;
+  for (i=0;i<max; i++)
+    {
+      __builtin_memset (a, 10, size * sizeof (a[0]));
+      asm("");
+    }
+   return 0;
+}
+/* { dg-final-use { scan-ipa-dump "Single value 4 stringop" 
"tree_profile_ipa"} } */
+/* The versioned memset of size 4 should be optimized to an assignment.  */
+/* { dg-final-use { scan-tree-dump "a\\\[0\\\] = 168430090" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/update-loopch.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/update-loopch.c     (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/update-loopch.c     (revision 0)
@@ -0,0 +1,21 @@
+/* { dg-options "-O2 -fdump-ipa-tree_profile_ipa-blocks 
-fdump-tree-optimized-blocks" } */
+int max = 33333;
+int a[8];
+int
+main ()
+{
+  int i;
+  for (i = 0; i < max; i++)
+    {
+      a[i % 8]++;
+    }
+  return 0;
+}
+/* Loop header copying will peel away the initial conditional, so the loop body
+   is once reached directly from entry point of function, rest via loopback
+   edge.  */
+/* { dg-final-use { scan-ipa-dump "count:33333" "tree_profile_ipa"} } */
+/* { dg-final-use { scan-tree-dump "count:33332" "optimized"} } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.040i.tree_profile_ipa
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.040i.tree_profile_ipa     
(revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.040i.tree_profile_ipa     
(revision 0)
@@ -0,0 +1,306 @@
+Abnormal edge 3 to 1 put to tree
+Abnormal edge 4 to 1 put to tree
+Abnormal edge 7 to 1 put to tree
+Normal edge 0 to 2 put to tree
+Normal edge 2 to 6 put to tree
+Normal edge 4 to 5 put to tree
+8 basic blocks
+10 edges
+0 ignored edges
+Stmt p.0_3 ();
+Indirect call -- top N
+Merged 1 profiles with maximal count 10.
+
+Read edge from 3 to 4, count:10
+Read edge from 5 to 6, count:10
+Read edge from 6 to 3, count:10
+Read edge from 6 to 7, count:1
+4 edge counts read
+
+8 basic blocks, 10 edges.
+
+Basic block 0 , next 2, loop_depth 0, count 1, freq 909, maybe hot.
+Predecessors: 
+Successors:  2 [100.0%]  count:1 (fallthru,exec)
+
+Basic block 2 , prev 0, next 3, loop_depth 0, count 1, freq 909, maybe hot.
+Predecessors:  ENTRY [100.0%]  count:1 (fallthru,exec)
+Successors:  6 [100.0%]  count:1 (fallthru,exec)
+
+Basic block 3 , prev 2, next 4, loop_depth 1, count 10, freq 9091, maybe hot.
+Predecessors:  6 [90.9%]  count:10 (true,exec)
+Successors:  4 [100.0%]  count:10 (fallthru) EXIT (fake)
+
+Basic block 4 , prev 3, next 5, loop_depth 1, count 10, freq 9091, maybe hot.
+Predecessors:  3 [100.0%]  count:10 (fallthru)
+Successors:  5 [100.0%]  count:10 (fallthru) EXIT (fake)
+
+Basic block 5 , prev 4, next 6, loop_depth 1, count 10, freq 9091, maybe hot.
+Predecessors:  4 [100.0%]  count:10 (fallthru)
+Successors:  6 [100.0%]  count:10 (fallthru,dfs_back,exec)
+
+Basic block 6 , prev 5, next 7, loop_depth 1, count 11, freq 10000, maybe hot.
+Predecessors:  2 [100.0%]  count:1 (fallthru,exec) 5 [100.0%]  count:10 
(fallthru,dfs_back,exec)
+Successors:  3 [90.9%]  count:10 (true,exec) 7 [9.1%]  count:1 (false,exec)
+
+Basic block 7 , prev 6, next 1, loop_depth 0, count 1, freq 909, maybe hot.
+Predecessors:  6 [9.1%]  count:1 (false,exec)
+Successors:  EXIT [100.0%]  count:1
+
+Basic block 1 , prev 7, loop_depth 0, count 1, freq 909, maybe hot.
+Predecessors:  7 [100.0%]  count:1 4 (fake) 3 (fake)
+Successors: 
+
+Graph solving took 3 passes.
+
+1 branches
+0% branches in range 0-5%
+100% branches in range 5-10%
+0% branches in range 10-15%
+0% branches in range 15-20%
+0% branches in range 20-25%
+0% branches in range 25-30%
+0% branches in range 30-35%
+0% branches in range 35-40%
+0% branches in range 40-45%
+0% branches in range 45-50%
+
+
+Trying transformations on stmt p.0_3 ();
+Indirect call -- top N
+Indirect call -> direct call p.0_3=> a1 (module_id:1, func_id:1)
+Transformation on insn:
+p.0_3 ();
+==>
+a1 ();
+hist->count 9 hist->all 10
+Analyzing function body size: main
+  freq: 10001 size:  3 time: 12 setp (&p, i_1);
+  freq: 10001 size:  1 time:  1 p.0_3 = p;
+  freq: 10001 size:  0 time:  0 PROF.1_10 = p.0_3;
+  freq: 10001 size:  0 time:  0 PROF.1_11 = (void *) a1;
+  freq: 10001 size:  2 time:  2 if (PROF.1_11 == PROF.1_10)
+  freq:  9001 size:  2 time: 11 a1 ();
+  freq:  1000 size:  2 time: 11 p.0_3 ();
+  freq: 10001 size:  1 time:  1 i_4 = i_1 + 1;
+  freq: 11001 size:  2 time:  2 if (i_1 <= 9)
+  freq:  1000 size:  1 time:  2 return 0;
+Overall function body time: 294-2 size: 16-3
+With function call overhead time: 294-13 size: 16-5
+Abnormal edge 5 to 1 put to tree
+Normal edge 0 to 2 put to tree
+Normal edge 2 to 3 put to tree
+Normal edge 2 to 4 put to tree
+6 basic blocks
+6 edges
+0 ignored edges
+Merged 1 profiles with maximal count 10.
+
+Read edge from 3 to 5, count:1
+Read edge from 4 to 5, count:9
+2 edge counts read
+
+6 basic blocks, 6 edges.
+
+Basic block 0 , next 2, loop_depth 0, count 10, freq 10000, maybe hot.
+Predecessors: 
+Successors:  2 [100.0%]  count:10 (fallthru,exec)
+
+Basic block 2 , prev 0, next 3, loop_depth 0, count 10, freq 10000, maybe hot.
+Predecessors:  ENTRY [100.0%]  count:10 (fallthru,exec)
+Successors:  3 [39.0%]  count:1 (true,exec) 4 [61.0%]  count:9 (false,exec)
+
+Basic block 3 , prev 2, next 4, loop_depth 0, count 1, freq 3900, maybe hot.
+Predecessors:  2 [39.0%]  count:1 (true,exec)
+Successors:  5 [100.0%]  count:1 (fallthru,exec)
+
+Basic block 4 , prev 3, next 5, loop_depth 0, count 9, freq 6100, maybe hot.
+Predecessors:  2 [61.0%]  count:9 (false,exec)
+Successors:  5 [100.0%]  count:9 (fallthru,exec)
+
+Basic block 5 , prev 4, next 1, loop_depth 0, count 10, freq 10000, maybe hot.
+Predecessors:  3 [100.0%]  count:1 (fallthru,exec) 4 [100.0%]  count:9 
(fallthru,exec)
+Successors:  EXIT [100.0%]  count:10
+
+Basic block 1 , prev 5, loop_depth 0, count 10, freq 10000, maybe hot.
+Predecessors:  5 [100.0%]  count:10
+Successors: 
+
+Graph solving took 3 passes.
+
+1 branches
+0% branches in range 0-5%
+0% branches in range 5-10%
+100% branches in range 10-15%
+0% branches in range 15-20%
+0% branches in range 20-25%
+0% branches in range 25-30%
+0% branches in range 30-35%
+0% branches in range 35-40%
+0% branches in range 40-45%
+0% branches in range 45-50%
+
+
+Abnormal edge 2 to 1 put to tree
+3 basic blocks
+2 edges
+0 ignored edges
+Merged 1 profiles with maximal count 10.
+
+Read edge from 0 to 2, count:1
+1 edge counts read
+
+3 basic blocks, 2 edges.
+
+Basic block 0 , next 2, loop_depth 0, count 1, freq 10000, maybe hot.
+Predecessors: 
+Successors:  2 [100.0%]  count:1 (fallthru,exec)
+
+Basic block 2 , prev 0, next 1, loop_depth 0, count 1, freq 10000, maybe hot.
+Predecessors:  ENTRY [100.0%]  count:1 (fallthru,exec)
+Successors:  EXIT [100.0%]  count:1
+
+Basic block 1 , prev 2, loop_depth 0, count 1, freq 10000, maybe hot.
+Predecessors:  2 [100.0%]  count:1
+Successors: 
+
+Graph solving took 3 passes.
+
+0 branches
+
+
+Abnormal edge 2 to 1 put to tree
+3 basic blocks
+2 edges
+0 ignored edges
+Merged 1 profiles with maximal count 10.
+
+Read edge from 0 to 2, count:9
+1 edge counts read
+
+3 basic blocks, 2 edges.
+
+Basic block 0 , next 2, loop_depth 0, count 9, freq 10000, maybe hot.
+Predecessors: 
+Successors:  2 [100.0%]  count:9 (fallthru,exec)
+
+Basic block 2 , prev 0, next 1, loop_depth 0, count 9, freq 10000, maybe hot.
+Predecessors:  ENTRY [100.0%]  count:9 (fallthru,exec)
+Successors:  EXIT [100.0%]  count:9
+
+Basic block 1 , prev 2, loop_depth 0, count 9, freq 10000, maybe hot.
+Predecessors:  2 [100.0%]  count:9
+Successors: 
+
+Graph solving took 3 passes.
+
+0 branches
+
+
+
+
+Symbols to be put in SSA form
+
+{ .MEM }
+
+
+Incremental SSA update started at block: 0
+
+Number of blocks in CFG: 11
+Number of blocks to update: 10 ( 91%)
+
+
+
+main ()
+{
+  void * PROF.1;
+  int i;
+  int (*<T352>) (void) p;
+  int (*<T352>) (void) p.0;
+
+<bb 2>:
+  goto <bb 6>;
+
+<bb 3>:
+  setp (&p, i_1);
+
+<bb 4>:
+  p.0_3 = p;
+  PROF.1_10 = p.0_3;
+  PROF.1_11 = (void *) a1;
+  if (PROF.1_11 == PROF.1_10)
+    goto <bb 8>;
+  else
+    goto <bb 9>;
+
+<bb 8>:
+  a1 ();
+  goto <bb 10>;
+
+<bb 9>:
+  p.0_3 ();
+
+<bb 10>:
+
+<bb 5>:
+  i_4 = i_1 + 1;
+
+<bb 6>:
+  # i_1 = PHI <0(2), i_4(5)>
+  if (i_1 <= 9)
+    goto <bb 3>;
+  else
+    goto <bb 7>;
+
+<bb 7>:
+  return 0;
+
+}
+
+
+setp (int (*<T352>) (void) * pp, int i)
+{
+  int (*tp) (void) D.4264;
+  int D.4263;
+  int D.4262;
+  int (*tp) (void) D.4260;
+
+<bb 2>:
+  if (i_1(D) == 0)
+    goto <bb 3>;
+  else
+    goto <bb 4>;
+
+<bb 3>:
+  D.4260_2 = aa[i_1(D)];
+  *pp_3(D) = D.4260_2;
+  goto <bb 5>;
+
+<bb 4>:
+  D.4262_4 = i_1(D) & 2;
+  D.4263_5 = D.4262_4 + 1;
+  D.4264_6 = aa[D.4263_5];
+  *pp_3(D) = D.4264_6;
+
+<bb 5>:
+  return;
+
+}
+
+
+a2 ()
+{
+<bb 2>:
+  return 0;
+
+}
+
+
+a1 ()
+{
+<bb 2>:
+  return 10;
+
+}
+
+
Index: testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1.c       (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1.c       (revision 0)
@@ -0,0 +1,19 @@
+/* { dg-options "-O2 -fdump-ipa-tree_profile_ipa" } */
+/* { dg-additional-sources "ic-misattribution-1a.c" } */
+
+extern void other_caller (void);
+
+void
+callee (void)
+{
+  return;
+}
+
+void
+caller(void (*func) (void))
+{
+  func ();
+}
+
+/* { dg-final-use { scan-ipa-dump "hist->count 1 hist->all 1" 
"tree_profile_ipa" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/update-tailcall.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/update-tailcall.c   (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/update-tailcall.c   (revision 0)
@@ -0,0 +1,20 @@
+/* { dg-options "-O2 -fdump-tree-tailc -fdump-tree-optimized" } */
+__attribute__ ((noinline))
+int factorial(int x)
+{
+   if (x == 1)
+     return 1;
+   else
+     return x*factorial(--x);
+}
+int gbl;
+int
+main()
+{
+   gbl = factorial(100);
+   return 0;
+}
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "tailc"} } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "tailc" } } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1a.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1a.c      (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/ic-misattribution-1a.c      (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-options "-DEMPTY" } */
+/* This file is only needed in combination with ic-misattribution-1.c
+   but there's no easy way to make this file ignored. */
+extern void callee (void);
+extern void caller (void (*func) (void));
+
+typedef void (*func_t) (void);
+func_t func;
+
+int
+main ()
+{
+#ifdef EMPTY
+#else
+  func = callee;
+  caller (callee);
+  func ();
+#endif
+  return 0;
+}
+
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/lipo.exp
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/lipo.exp    (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/lipo.exp    (revision 0)
@@ -0,0 +1,54 @@
+# Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Test the functionality of programs compiled with profile-directed block
+# ordering using -fprofile-generate followed by -fbranch-use.
+
+load_lib target-supports.exp
+
+# Some targets don't support tree profiling.
+if { ![check_profiling_available ""] } {
+    return
+}
+
+# The procedures in profopt.exp need these parameters.
+set tool gcc
+set prof_ext "gcda"
+
+# Override the list defined in profopt.exp.
+set PROFOPT_OPTIONS [list {}]
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+# Load support procs.
+load_lib profopt.exp
+
+# These are globals used by profopt-execute.  The first is options
+# needed to generate profile data, the second is options to use the
+# profile data.
+set profile_option "-fprofile-generate -fripa -D_PROFILE_GENERATE"
+set feedback_option "-fprofile-use -fripa -D_PROFILE_USE"
+
+foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] {
+    # If we're only testing specific files and this isn't one of them, skip it.
+    if ![runtest_file_p $runtests $src] then {
+        continue
+    }
+    profopt-execute $src
+}
Index: testsuite/gcc.dg/tree-prof/lipo/tracer-1.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/tracer-1.c  (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/tracer-1.c  (revision 0)
@@ -0,0 +1,18 @@
+/* { dg-options "-O2 -ftracer -fdump-tree-tracer" } */
+volatile int a, b, c;
+int main ()
+{
+  int i;
+  for (i = 0; i < 1000; i++)
+    {
+      if (i % 17)
+       a++;
+      else
+       b++;
+      c++;
+    }
+  return 0;
+}
+/* Superblock formation should produce two copies of the increment of c */
+/* { dg-final-generate { scan-tree-dump-times "c =" 2 "tracer" } } */
+/* { dg-final-use { cleanup-tree-dump "tracer" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.145t.optimized
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.145t.optimized    
(revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c.145t.optimized    
(revision 0)
@@ -0,0 +1,229 @@
+
+;; Function a1 (a1)[1:1] (unlikely executed)
+
+a1 ()
+{
+  # BLOCK 2 freq:10000
+  # PRED: ENTRY [100.0%]  count:9 (fallthru,exec)
+  return 10;
+  # SUCC: EXIT [100.0%] 
+
+}
+
+
+
+;; Function a2 (a2)[1:2]
+
+a2 ()
+{
+  # BLOCK 2 freq:10000 count:1
+  # PRED: ENTRY [100.0%]  count:1 (fallthru,exec)
+  return 0;
+  # SUCC: EXIT [100.0%]  count:1
+
+}
+
+
+
+;; Function setp (setp)[1:3]
+
+Merging blocks 3 and 5
+Merging blocks 4 and 6
+setp (int (*<T352>) (void) * pp, int i)
+{
+  int (*tp) (void) D.4264;
+  int D.4263;
+  int D.4262;
+
+  # BLOCK 2 freq:10000 count:10
+  # PRED: ENTRY [100.0%]  count:10 (fallthru,exec)
+  if (i_1(D) == 0)
+    goto <bb 3>;
+  else
+    goto <bb 4>;
+  # SUCC: 3 [10.0%]  count:1 (true,exec) 4 [90.0%]  count:9 (false,exec)
+
+  # BLOCK 3 freq:1000 count:1
+  # PRED: 2 [10.0%]  count:1 (true,exec)
+  *pp_3(D) = a2;
+  return;
+  # SUCC: EXIT [100.0%]  count:1
+
+  # BLOCK 4 freq:9000 count:9
+  # PRED: 2 [90.0%]  count:9 (false,exec)
+  D.4262_4 = i_1(D) & 2;
+  D.4263_5 = D.4262_4 + 1;
+  D.4264_6 = aa[D.4263_5];
+  *pp_3(D) = D.4264_6;
+  return;
+  # SUCC: EXIT [100.0%]  count:9
+
+}
+
+
+
+;; Function main (main)[1:4] (executed once)
+
+main ()
+{
+  int (*<T352>) (void) p;
+  int (*<T352>) (void) p.0;
+
+  # BLOCK 2 freq:909 count:1
+  # PRED: ENTRY [100.0%]  count:1 (fallthru,exec)
+  setp (&p, 0);
+  p.0_18 = p;
+  if (p.0_18 == a1)
+    goto <bb 4>;
+  else
+    goto <bb 3>;
+  # SUCC: 4 [90.0%]  count:1 (true,exec) 3 [10.0%]  (false,exec)
+
+  # BLOCK 3 freq:91
+  # PRED: 2 [10.0%]  (false,exec)
+  p.0_18 ();
+  # SUCC: 4 [100.0%]  (fallthru,exec)
+
+  # BLOCK 4 freq:909 count:1
+  # PRED: 2 [90.0%]  count:1 (true,exec) 3 [100.0%]  (fallthru,exec)
+  setp (&p, 1);
+  p.0_27 = p;
+  if (p.0_27 == a1)
+    goto <bb 6>;
+  else
+    goto <bb 5>;
+  # SUCC: 6 [90.0%]  count:1 (true,exec) 5 [10.0%]  (false,exec)
+
+  # BLOCK 5 freq:91
+  # PRED: 4 [10.0%]  (false,exec)
+  p.0_27 ();
+  # SUCC: 6 [100.0%]  (fallthru,exec)
+
+  # BLOCK 6 freq:909 count:1
+  # PRED: 4 [90.0%]  count:1 (true,exec) 5 [100.0%]  (fallthru,exec)
+  setp (&p, 2);
+  p.0_36 = p;
+  if (p.0_36 == a1)
+    goto <bb 8>;
+  else
+    goto <bb 7>;
+  # SUCC: 8 [90.0%]  count:1 (true,exec) 7 [10.0%]  (false,exec)
+
+  # BLOCK 7 freq:91
+  # PRED: 6 [10.0%]  (false,exec)
+  p.0_36 ();
+  # SUCC: 8 [100.0%]  (fallthru,exec)
+
+  # BLOCK 8 freq:909 count:1
+  # PRED: 6 [90.0%]  count:1 (true,exec) 7 [100.0%]  (fallthru,exec)
+  setp (&p, 3);
+  p.0_45 = p;
+  if (p.0_45 == a1)
+    goto <bb 10>;
+  else
+    goto <bb 9>;
+  # SUCC: 10 [90.0%]  count:1 (true,exec) 9 [10.0%]  (false,exec)
+
+  # BLOCK 9 freq:91
+  # PRED: 8 [10.0%]  (false,exec)
+  p.0_45 ();
+  # SUCC: 10 [100.0%]  (fallthru,exec)
+
+  # BLOCK 10 freq:909 count:1
+  # PRED: 8 [90.0%]  count:1 (true,exec) 9 [100.0%]  (fallthru,exec)
+  setp (&p, 4);
+  p.0_54 = p;
+  if (p.0_54 == a1)
+    goto <bb 12>;
+  else
+    goto <bb 11>;
+  # SUCC: 12 [90.0%]  count:1 (true,exec) 11 [10.0%]  (false,exec)
+
+  # BLOCK 11 freq:91
+  # PRED: 10 [10.0%]  (false,exec)
+  p.0_54 ();
+  # SUCC: 12 [100.0%]  (fallthru,exec)
+
+  # BLOCK 12 freq:909 count:1
+  # PRED: 10 [90.0%]  count:1 (true,exec) 11 [100.0%]  (fallthru,exec)
+  setp (&p, 5);
+  p.0_63 = p;
+  if (p.0_63 == a1)
+    goto <bb 14>;
+  else
+    goto <bb 13>;
+  # SUCC: 14 [90.0%]  count:1 (true,exec) 13 [10.0%]  (false,exec)
+
+  # BLOCK 13 freq:91
+  # PRED: 12 [10.0%]  (false,exec)
+  p.0_63 ();
+  # SUCC: 14 [100.0%]  (fallthru,exec)
+
+  # BLOCK 14 freq:909 count:1
+  # PRED: 12 [90.0%]  count:1 (true,exec) 13 [100.0%]  (fallthru,exec)
+  setp (&p, 6);
+  p.0_72 = p;
+  if (p.0_72 == a1)
+    goto <bb 16>;
+  else
+    goto <bb 15>;
+  # SUCC: 16 [90.0%]  count:1 (true,exec) 15 [10.0%]  (false,exec)
+
+  # BLOCK 15 freq:91
+  # PRED: 14 [10.0%]  (false,exec)
+  p.0_72 ();
+  # SUCC: 16 [100.0%]  (fallthru,exec)
+
+  # BLOCK 16 freq:909 count:1
+  # PRED: 14 [90.0%]  count:1 (true,exec) 15 [100.0%]  (fallthru,exec)
+  setp (&p, 7);
+  p.0_81 = p;
+  if (p.0_81 == a1)
+    goto <bb 18>;
+  else
+    goto <bb 17>;
+  # SUCC: 18 [90.0%]  count:1 (true,exec) 17 [10.0%]  (false,exec)
+
+  # BLOCK 17 freq:91
+  # PRED: 16 [10.0%]  (false,exec)
+  p.0_81 ();
+  # SUCC: 18 [100.0%]  (fallthru,exec)
+
+  # BLOCK 18 freq:909 count:1
+  # PRED: 16 [90.0%]  count:1 (true,exec) 17 [100.0%]  (fallthru,exec)
+  setp (&p, 8);
+  p.0_90 = p;
+  if (p.0_90 == a1)
+    goto <bb 20>;
+  else
+    goto <bb 19>;
+  # SUCC: 20 [90.0%]  count:1 (true,exec) 19 [10.0%]  (false,exec)
+
+  # BLOCK 19 freq:91
+  # PRED: 18 [10.0%]  (false,exec)
+  p.0_90 ();
+  # SUCC: 20 [100.0%]  (fallthru,exec)
+
+  # BLOCK 20 freq:909 count:1
+  # PRED: 18 [90.0%]  count:1 (true,exec) 19 [100.0%]  (fallthru,exec)
+  setp (&p, 9);
+  p.0_3 = p;
+  if (p.0_3 == a1)
+    goto <bb 22>;
+  else
+    goto <bb 21>;
+  # SUCC: 22 [90.0%]  count:1 (true,exec) 21 [10.0%]  (false,exec)
+
+  # BLOCK 21 freq:91
+  # PRED: 20 [10.0%]  (false,exec)
+  p.0_3 ();
+  # SUCC: 22 [100.0%]  (fallthru,exec)
+
+  # BLOCK 22 freq:909 count:1
+  # PRED: 21 [100.0%]  (fallthru,exec) 20 [90.0%]  count:1 (true,exec)
+  return 0;
+  # SUCC: EXIT [100.0%]  count:1
+
+}
+
+
Index: testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c   (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.c   (revision 0)
@@ -0,0 +1,43 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+
+static int a1 (void)
+{
+    return 10;
+}
+
+static int a2 (void)
+{
+    return 0;
+}
+
+typedef int (*tp) (void);
+
+static tp aa [] = {a2, a1, a1, a1, a1};
+
+__attribute__((noinline)) void setp (int (**pp) (void), int i)
+{
+  if (!i)
+    *pp = aa [i];
+  else
+    *pp = aa [(i & 2) + 1];
+}
+
+int
+main (void)
+{
+  int (*p) (void);
+  int  i;
+
+  for (i = 0; i < 10; i ++)
+    {
+       setp (&p, i);
+       p ();
+    }
+  
+  return 0;
+}
+
+/* { dg-final-use { scan-ipa-dump "Indirect call -> direct call.* a1" 
"tree_profile_ipa"} } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-1.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/val-prof-1.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/val-prof-1.c        (revision 0)
@@ -0,0 +1,22 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+int a[1000];
+int b = 256;
+int c = 257;
+main ()
+{
+  int i;
+  int n;
+  for (i = 0; i < 1000; i++)
+    {
+      if (i % 17)
+       n = c;
+      else n = b;
+      a[i] /= n;
+    }
+  return 0;
+}
+/* { dg-final-use { scan-ipa-dump "Div.mod by constant n_\[0-9\]*=257 
transformation on insn" "tree_profile_ipa"} } */
+/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* != 257\\)" "optimized"} } 
*/
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/wcoverage-mismatch.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/wcoverage-mismatch.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/wcoverage-mismatch.c        (revision 0)
@@ -0,0 +1,20 @@
+/* { dg-options "-O2 -Wno-coverage-mismatch" } */
+
+int __attribute__((noinline)) bar (void)
+{
+}
+
+int foo (int i)
+{
+#ifdef _PROFILE_USE
+  if (i)
+    bar ();
+#endif
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  foo (argc);
+  return 0;
+}
Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-2.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/val-prof-2.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/val-prof-2.c        (revision 0)
@@ -0,0 +1,32 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+unsigned int a[1000];
+unsigned int b = 256;
+unsigned int c = 1024;
+unsigned int d = 17;
+main ()
+{
+  int i;
+  unsigned int n;
+  for (i = 0; i < 1000; i++)
+    {
+           a[i]=100*i;
+    }
+  for (i = 0; i < 1000; i++)
+    {
+      if (i % 2)
+       n = b;
+      else if (i % 3)
+       n = c;
+      else
+       n = d;
+      a[i] %= n;
+    }
+  return 0;
+}
+/* { dg-final-use { scan-ipa-dump "Mod power of 2 transformation on insn" 
"tree_profile_ipa" } } */
+/* This is part of code checking that n is power of 2, so we are sure that the 
transformation
+   didn't get optimized out.  */
+/* { dg-final-use { scan-tree-dump "n_\[0-9\]* \\+ 0xffff" "optimized"} } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/pr45354.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/pr45354.c   (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/pr45354.c   (revision 0)
@@ -0,0 +1,43 @@
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O -freorder-blocks-and-partition -fschedule-insns 
-fselective-scheduling" { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+
+extern void abort (void);
+
+int ifelse_val2;
+
+int __attribute__((noinline))
+test_ifelse2 (int i)
+{
+  int result = 0;
+  if (!i)                              /* count(6) */
+    result = 1;                                /* count(1) */
+  if (i == 1)                          /* count(6) */
+    result = 1024;
+  if (i == 2)                          /* count(6) */
+    result = 2;                                /* count(3) */
+  if (i == 3)                          /* count(6) */
+    return 8;                          /* count(2) */
+  if (i == 4)                          /* count(4) */
+    return 2048;
+  return result;                       /* count(4) */
+}
+
+void __attribute__((noinline))
+call_ifelse ()
+{
+  ifelse_val2 += test_ifelse2 (0);
+  ifelse_val2 += test_ifelse2 (2);
+  ifelse_val2 += test_ifelse2 (2);
+  ifelse_val2 += test_ifelse2 (2);
+  ifelse_val2 += test_ifelse2 (3);
+  ifelse_val2 += test_ifelse2 (3);
+}
+
+int
+main()
+{
+  call_ifelse ();
+  if (ifelse_val2 != 23)
+    abort ();
+  return 0;
+}
Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-3.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/val-prof-3.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/val-prof-3.c        (revision 0)
@@ -0,0 +1,32 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+unsigned int a[1000];
+unsigned int b = 257;
+unsigned int c = 1023;
+unsigned int d = 19;
+main ()
+{
+  int i;
+  unsigned int n;
+  for (i = 0; i < 1000; i++)
+    {
+           a[i]=18;
+    }
+  for (i = 0; i < 1000; i++)
+    {
+      if (i % 2)
+       n = b;
+      else if (i % 3)
+       n = c;
+      else
+       n = d;
+      a[i] %= n;
+    }
+  return 0;
+}
+/* { dg-final-use { scan-ipa-dump "Mod subtract transformation on insn" 
"tree_profile_ipa" } } */
+/* This is part of code checking that n is greater than the divisor so we are 
sure that it
+   didn't get optimized out.  */
+/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-4.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/val-prof-4.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/val-prof-4.c        (revision 0)
@@ -0,0 +1,32 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+unsigned int a[1000];
+unsigned int b = 999;
+unsigned int c = 1002;
+unsigned int d = 1003;
+main ()
+{
+  int i;
+  unsigned int n;
+  for (i = 0; i < 1000; i++)
+    {
+           a[i]=1000+i;
+    }
+  for (i = 0; i < 1000; i++)
+    {
+      if (i % 2)
+       n = b;
+      else if (i % 3)
+       n = c;
+      else
+       n = d;
+      a[i] %= n;
+    }
+  return 0;
+}
+/* { dg-final-use { scan-ipa-dump "Mod subtract transformation on insn" 
"tree_profile_ipa" } } */
+/* This is part of code checking that n is greater than the divisor so we are 
sure that it
+   didn't get optimized out.  */
+/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-5.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/val-prof-5.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/val-prof-5.c        (revision 0)
@@ -0,0 +1,17 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+int a[1000];
+int b=997;
+main()
+{
+       int i;
+       for (i = 0; i < 1000; i++)
+               if (a[i])
+                       a[i]/=b;
+               else
+                       a[i]/=b;
+       return 0;
+}
+/* { dg-final-use { scan-ipa-dump "Div.mod by constant b.*=997 transformation 
on insn" "tree_profile_ipa" } } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-6.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/val-prof-6.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/val-prof-6.c        (revision 0)
@@ -0,0 +1,20 @@
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+char a[1000];
+char b[1000];
+int size=1000;
+__attribute__ ((noinline))
+t(int size)
+{
+  __builtin_memcpy(a,b,size);
+}
+int
+main()
+{
+  int i;
+  for (i=0; i < size; i++)
+    t(i);
+  return 0;
+}
+/* { dg-final-use { scan-tree-dump "Average value sum:499500" "optimized"} } */
+/* { dg-final-use { scan-tree-dump "IOR value" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/val-prof-7.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/val-prof-7.c        (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/val-prof-7.c        (revision 0)
@@ -0,0 +1,26 @@
+/* { dg-options "-O2 -fdump-ipa-tree_profile_ipa -mtune=core2" } */
+/* { dg-skip-if "" { ! { i?86-*-* x86_64-*-* } } { "*" } { "" } } */
+
+#include <strings.h>
+
+int foo(int len)
+{
+  char array[1000];
+  bzero(array, len);
+  return 0;
+}
+
+int main() {
+  int i;
+  for (i = 0; i < 1000; i++)
+    {
+      if (i > 990)
+       foo(16);
+      else
+       foo(8);
+    }
+  return 0;
+}
+
+/* { dg-final-use { scan-ipa-dump "Single value 8 stringop transformation on 
bzero" "tree_profile_ipa" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/gcc.dg/tree-prof/lipo/indir-call-prof.gcda.imports
===================================================================
Index: testsuite/gcc.dg/tree-prof/lipo/pr47187.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/pr47187.c   (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/pr47187.c   (revision 0)
@@ -0,0 +1,23 @@
+/* PR bootstrap/47187 */
+/* { dg-options "-O2" } */
+
+char buf[64];
+char buf2[64];
+
+void *
+foo (char *p, long size)
+{
+  return __builtin_memcpy (buf, p, size);
+}
+
+int
+main (void)
+{
+  long i;
+  for (i = 0; i < 65536; i++)
+    if (foo ("abcdefghijkl", 12) != buf)
+      __builtin_abort ();
+  if (foo (buf2, 64) != buf)
+    __builtin_abort ();
+  return 0;
+}
Index: testsuite/gcc.dg/tree-prof/lipo/update-cunroll-2.c
===================================================================
--- testsuite/gcc.dg/tree-prof/lipo/update-cunroll-2.c  (revision 0)
+++ testsuite/gcc.dg/tree-prof/lipo/update-cunroll-2.c  (revision 0)
@@ -0,0 +1,21 @@
+
+/* { dg-options "-O2 -fdump-tree-optimized-blocks" } */
+int a[8];
+__attribute__ ((noinline))
+int t()
+{
+       int i;
+       for (i = 0; i < 3; i++)
+               if (a[i])
+                       break;
+       return i;
+}
+main ()
+{
+  int i;
+  for (i = 0; i < 1000; i++)
+    t ();
+  return 0;
+}
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
Index: testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args.C      (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args.C      (revision 0)
@@ -0,0 +1,36 @@
+/* { dg-options "-O2 -fdump-tree-einline" } */
+class DocId {
+ public:
+ DocId() { }
+ DocId(const DocId &other) {  }
+};
+
+int g;
+class Base {
+ public:
+ virtual void Foo(DocId id) { g++; }
+};
+
+class Super: public Base {
+ public:
+ void Foo(DocId id) { }
+ void Bar(Base *base, DocId id) __attribute__((noinline));
+};
+
+void Super::Bar(Base *base, DocId id) {
+ Super::Foo(id); // direct call is inlined
+ base->Foo(id); // indirect call is marked do not inline
+}
+
+int main(void)
+{
+ Base bah;
+ Super baz;
+ DocId gid;
+
+ baz.Bar(&baz, gid);
+ return 0;
+}
+/* { dg-final-use { scan-tree-dump "Inlining .*Super::Foo" "einline" } } */
+/* { dg-final-use { scan-tree-dump-not "mismatched arguments" "einline" } } */
+/* { dg-final-use { cleanup-tree-dump "einline" } } */
Index: testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2.C (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2.C (revision 0)
@@ -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: testsuite/g++.dg/tree-prof/lipo/indir-call-prof.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/indir-call-prof.C   (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/indir-call-prof.C   (revision 0)
@@ -0,0 +1,39 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-tree_profile_ipa" } */
+
+struct A {
+  A () {}
+
+  virtual int AA (void)
+  { return 0; }
+
+};
+
+struct B : public A {
+  B () {}
+
+  virtual int AA (void)
+  { return 1; }
+};
+
+void * __attribute__((noinline,noclone)) wrap (void *p) { return p; }
+int
+main (void)
+{
+  A a;
+  B b;
+  
+  A* p;
+
+  p = (A *)wrap ((void *)&a);
+  p->AA ();
+
+  p = (B *)wrap ((void *)&b);
+  p->AA ();
+  
+  return 0;
+}
+
+/* { dg-final-use { scan-ipa-dump "Indirect call -> direct call.* AA " 
"tree_profile_ipa" } } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized" } } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "tree_profile_ipa" } } */
Index: testsuite/g++.dg/tree-prof/lipo/partition1.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/partition1.C        (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/partition1.C        (revision 0)
@@ -0,0 +1,54 @@
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -freorder-blocks-and-partition" } */
+/* { dg-skip-if "PR target/47683" { mips-sgi-irix* } } */
+
+struct A { A () __attribute__((noinline)); ~A () __attribute__((noinline)); };
+A::A () { asm volatile ("" : : : "memory"); }
+A::~A () { asm volatile ("" : : : "memory"); }
+
+int bar () __attribute__((noinline));
+void foo () __attribute__((noinline));
+
+volatile int k, l;
+
+int bar (int i)
+{
+  void *p = __builtin_alloca (i);
+  asm volatile ("" : : "r" (i), "r" (p) : "memory");
+  if (k) throw 6;
+  return ++l;
+}
+
+void foo ()
+{
+  A a;
+  try {
+    A b;
+    int i = bar (5);
+    try { throw 6; } catch (int) {}
+    if (__builtin_expect (i < 4500, 0)) {
+      bar (7);
+      try { bar (8); } catch (long) {}
+      bar (10);
+      if (__builtin_expect (i < 0, 0)) {
+       try { bar (12); } catch (...) {}
+       bar (16);
+       bar (122);
+      } else {
+       try { bar (bar (7)); } catch (int) {}
+      }
+    } else {
+      try { bar (bar (bar (9))); } catch (...) {}
+      bar (5);
+    }
+  } catch (...) {
+  }
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 10000; i++)
+    foo ();
+}
Index: testsuite/g++.dg/tree-prof/lipo/partition2.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/partition2.C        (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/partition2.C        (revision 0)
@@ -0,0 +1,16 @@
+// PR middle-end/45458
+// { dg-require-effective-target freorder }
+// { dg-options "-fnon-call-exceptions -freorder-blocks-and-partition" }
+// { dg-skip-if "PR target/47683" { mips-sgi-irix* } }
+
+int
+main ()
+{
+  try
+  {
+    throw 6;
+  }
+  catch (...)
+  {
+  }
+}
Index: testsuite/g++.dg/tree-prof/lipo/partition3.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/partition3.C        (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/partition3.C        (revision 0)
@@ -0,0 +1,18 @@
+// PR middle-end/45566
+// { dg-require-effective-target freorder }
+// { dg-options "-O -fnon-call-exceptions -freorder-blocks-and-partition" }
+
+int k;
+
+int
+main ()
+{
+  try
+  {
+    if (k)
+      throw 6;
+  }
+  catch (...)
+  {
+  }
+}
Index: testsuite/g++.dg/tree-prof/lipo/lipo.exp
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/lipo.exp    (revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/lipo.exp    (revision 0)
@@ -0,0 +1,54 @@
+# Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Test the functionality of programs compiled with profile-directed block
+# ordering using -fprofile-generate followed by -fprofile-use.
+
+load_lib target-supports.exp
+
+# Some targets don't support tree profiling.
+if { ![check_profiling_available ""] } {
+    return
+}
+
+# The procedures in profopt.exp need these parameters.
+set tool g++
+set prof_ext "gcda"
+
+# Override the list defined in profopt.exp.
+set PROFOPT_OPTIONS [list {}]
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+# Load support procs.
+load_lib profopt.exp
+
+# These are globals used by profopt-execute.  The first is options
+# needed to generate profile data, the second is options to use the
+# profile data.
+set profile_option "-fprofile-generate -fripa"
+set feedback_option "-fprofile-use -fripa"
+
+foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.C]] {
+    # If we're only testing specific files and this isn't one of them, skip it.
+    if ![runtest_file_p $runtests $src] then {
+        continue
+    }
+    profopt-execute $src
+}
Index: dwarf2out.c
===================================================================
--- dwarf2out.c (revision 173136)
+++ dwarf2out.c (working copy)
@@ -4184,9 +4184,9 @@ dwarf2out_vms_end_prologue (unsigned int
   /* Output a label to mark the endpoint of the code generated for this
      function.  */
   ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL,
-                              current_function_funcdef_no);
+                              FUNC_LABEL_ID (cfun));
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, PROLOGUE_END_LABEL,
-                         current_function_funcdef_no);
+                         FUNC_LABEL_ID (cfun));
   fde = &fde_table[fde_table_in_use - 1];
   fde->dw_fde_vms_end_prologue = xstrdup (label);
 }
@@ -4209,9 +4209,9 @@ dwarf2out_vms_begin_epilogue (unsigned i
   /* Output a label to mark the endpoint of the code generated for this
      function.  */
   ASM_GENERATE_INTERNAL_LABEL (label, EPILOGUE_BEGIN_LABEL,
-                              current_function_funcdef_no);
+                              FUNC_LABEL_ID (cfun));
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, EPILOGUE_BEGIN_LABEL,
-                         current_function_funcdef_no);
+                         FUNC_LABEL_ID (cfun));
   fde->dw_fde_vms_begin_epilogue = xstrdup (label);
 }
 
@@ -17918,7 +17918,7 @@ dwarf2out_vms_debug_main_pointer (void)
   die->die_tag = DW_TAG_subprogram;
   add_name_attribute (die, VMS_DEBUG_MAIN_POINTER);
   ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL,
-                              current_function_funcdef_no);
+                              FUNC_LABEL_ID (cfun));
   add_AT_lbl_id (die, DW_AT_entry_pc, label);
 
   /* Make it the first child of comp_unit_die ().  */
Index: tree-profile.c
===================================================================
--- tree-profile.c      (revision 173136)
+++ tree-profile.c      (working copy)
@@ -473,7 +473,6 @@ gimple_gen_ic_func_profiler (void)
 static void
 gimple_gen_ic_func_topn_profiler (void)
 {
-  struct cgraph_node * c_node = cgraph_node (current_function_decl);
   gimple_stmt_iterator gsi;
   gimple stmt1;
   tree cur_func, gcov_info, cur_func_id;
@@ -483,16 +482,6 @@ gimple_gen_ic_func_topn_profiler (void)
       || DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (current_function_decl))
     return;
 
-  /* We want to make sure template functions are instrumented even though
-     it is not 'needed' in this module. It is possible that the function
-     is needed (e.g, as icall target) in another module. Note that for
-     functions in comdat groups, there is no guarantee which copy will be
-     picked up by the linker.  */
-
-  if (!c_node->needed
-      && (!c_node->reachable || !DECL_COMDAT (c_node->decl)))
-    return;
-
   gimple_init_edge_profiler ();
 
   gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
@@ -659,6 +648,7 @@ tree_profiling (void)
   /* Now perform link to allow cross module inlining.  */
   cgraph_do_link ();
   varpool_do_link ();
+  cgraph_unify_type_alias_sets ();
 
   init_node_map();
 
Index: l-ipo.c
===================================================================
--- l-ipo.c     (revision 173136)
+++ l-ipo.c     (working copy)
@@ -42,7 +42,12 @@ struct GTY(()) saved_module_scope
 
 static GTY (()) struct saved_module_scope *current_module_scope;
 static GTY ((param_is (struct saved_module_scope))) htab_t 
saved_module_scope_map;
-static int primary_module_last_fundef_no = 0;
+static int primary_module_last_funcdef_no = 0;
+/* Function id space for each module are qualified by the module id. After all 
the files
+   are parsed, we need to reset the funcdef_no to the max value from all 
module so that
+   the function clones do not assigned with ids colliding with some other 
orignal function
+   in the same module.  */
+static int max_funcdef_no = 0;
 static location_t primary_module_last_loc;
 /* Primary module pending templates.  */
 /* Referenced asm ids in primary module.  */
@@ -348,7 +353,7 @@ restore_post_parsing_states (void)
 {
   current_module_id = primary_module_id;
   current_module_scope = get_module_scope (primary_module_id);
-  set_funcdef_no (primary_module_last_fundef_no);
+  set_funcdef_no (max_funcdef_no);
   input_location = primary_module_last_loc;
 
   restore_assembler_name_reference_bit ();
@@ -364,6 +369,8 @@ void
 pop_module_scope (void)
 {
   bool is_last = false;
+  int  last_funcdef_no;
+
   if (!flag_dyn_ipa || !L_IPO_COMP_MODE)
     return;
 
@@ -379,13 +386,17 @@ pop_module_scope (void)
 
   is_last = is_last_module (current_module_id);
 
+  last_funcdef_no = get_last_funcdef_no ();
+  if (last_funcdef_no > max_funcdef_no)
+    max_funcdef_no = last_funcdef_no;
+
   lang_hooks.l_ipo.save_built_in_decl_post_module_parsing ();
   /* Save primary module state if needed (when module group
      size > 1)  */
   if (L_IPO_IS_PRIMARY_MODULE && num_in_fnames > 1)
     {
       save_assembler_name_reference_bit ();
-      primary_module_last_fundef_no = get_last_funcdef_no ();
+      primary_module_last_funcdef_no = last_funcdef_no;
     }
 
   if (!is_last)
Index: gcov-dump.c
===================================================================
--- gcov-dump.c (revision 173136)
+++ gcov-dump.c (working copy)
@@ -326,14 +326,15 @@ tag_function (const char *filename ATTRI
              unsigned tag ATTRIBUTE_UNUSED, unsigned length)
 {
   unsigned long pos = gcov_position ();
-  const char *name;
 
   printf (" ident=%u", gcov_read_unsigned ());
   printf (", checksum=0x%08x", gcov_read_unsigned ());
-  name = gcov_read_string ();
-  printf (", `%s'", name ? name : "NULL");
   if (gcov_position () - pos < length)
     {
+      const char *name;
+
+      name = gcov_read_string ();
+      printf (", `%s'", name ? name : "NULL");
       name = gcov_read_string ();
       printf (" %s", name ? name : "NULL");
       printf (":%u", gcov_read_unsigned ());

--
This patch is available for review at http://codereview.appspot.com/4444076

Reply via email to