OSDN Git Service

PR gcov-profile/34610
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 19 Jan 2008 17:49:46 +0000 (17:49 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 19 Jan 2008 17:49:46 +0000 (17:49 +0000)
* tree-cfg.c (make_edges): Mark both outgoing edges from
OMP_CONTINUE and from OMP_FOR as EDGE_ABNORMAL.
* omp-low.c (expand_omp_for): Clear EDGE_ABNORMAL bits
from OMP_FOR and OMP_CONTINUE outgoing edges.

* tree-profile.c (tree_profiling): Return early if
cfun->after_tree_profile != 0.  Set cfun->after_tree_profile
at the end.
* omp-low.c (expand_omp_parallel): Copy after_tree_profile
from cfun to child_cfun.
* function.h (struct function): Add after_tree_profile bit.

* gcc.dg/gomp/pr34610.c: New test.

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

gcc/ChangeLog
gcc/function.h
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/gomp/pr34610.c [new file with mode: 0644]
gcc/tree-cfg.c
gcc/tree-profile.c

index 49c9738..3fed0b2 100644 (file)
@@ -1,3 +1,18 @@
+2008-01-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR gcov-profile/34610
+       * tree-cfg.c (make_edges): Mark both outgoing edges from
+       OMP_CONTINUE and from OMP_FOR as EDGE_ABNORMAL.
+       * omp-low.c (expand_omp_for): Clear EDGE_ABNORMAL bits
+       from OMP_FOR and OMP_CONTINUE outgoing edges.
+
+       * tree-profile.c (tree_profiling): Return early if
+       cfun->after_tree_profile != 0.  Set cfun->after_tree_profile
+       at the end.
+       * omp-low.c (expand_omp_parallel): Copy after_tree_profile
+       from cfun to child_cfun.
+       * function.h (struct function): Add after_tree_profile bit.
+
 2008-01-19 Anatoly Sokolov <aesok@post.ru>
 
        * config/avr/avr.S (_exit): Disable interrupt.
index eb2a753..abc2303 100644 (file)
@@ -1,6 +1,7 @@
 /* Structure for saving state for a nested function.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -459,6 +460,9 @@ struct function GTY(())
   /* Nonzero if function being compiled needs to
      return the address of where it has put a structure value.  */
   unsigned int returns_pcc_struct : 1;
+
+  /* Nonzero if pass_tree_profile was run on this function.  */
+  unsigned int after_tree_profile : 1;
 };
 
 /* If va_list_[gf]pr_size is set to this, it means we don't know how
index 94d63b6..ca00266 100644 (file)
@@ -2497,6 +2497,9 @@ expand_omp_parallel (struct omp_region *region)
   entry_stmt = last_stmt (region->entry);
   child_fn = OMP_PARALLEL_FN (entry_stmt);
   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
+  /* If this function has been already instrumented, make sure
+     the child function isn't instrumented again.  */
+  child_cfun->after_tree_profile = cfun->after_tree_profile;
 
   entry_bb = region->entry;
   exit_bb = region->exit;
@@ -3337,6 +3340,16 @@ expand_omp_for (struct omp_region *region)
   extract_omp_for_data (last_stmt (region->entry), &fd);
   region->sched_kind = fd.sched_kind;
 
+  gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
+  BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
+  FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
+  if (region->cont)
+    {
+      gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
+      BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
+      FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
+    }
+
   if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
       && !fd.have_ordered
       && region->cont != NULL)
index 73c1e60..11e4ed4 100644 (file)
@@ -1,3 +1,8 @@
+2008-01-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR gcov-profile/34610
+       * gcc.dg/gomp/pr34610.c: New test.
+
 2008-01-19  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/34760
diff --git a/gcc/testsuite/gcc.dg/gomp/pr34610.c b/gcc/testsuite/gcc.dg/gomp/pr34610.c
new file mode 100644 (file)
index 0000000..95353a5
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR gcov-profile/34610 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fprofile-arcs -fopenmp" } */
+
+extern void bar (int);
+extern void baz (int) __attribute__((noreturn));
+
+void
+foo (int k)
+{
+  int i;
+#pragma omp for schedule(dynamic)
+  for (i = 0; i < 10; ++i)
+    bar (i);
+#pragma omp parallel for schedule(static)
+  for (i = 0; i < 10; ++i)
+    bar (i);
+#pragma omp parallel for schedule(static, 4)
+  for (i = 0; i < 10; ++i)
+    bar (i);
+  if (k)
+  #pragma omp for schedule(dynamic)
+    for (i = 0; i < 10; ++i)
+      baz (i);
+#pragma omp parallel
+  for (i = 0; i < 10; ++i)
+    bar (i);
+}
+
+/* { dg-final { cleanup-coverage-files } } */
index 8da55ff..c702502 100644 (file)
@@ -1,5 +1,5 @@
 /* Control flow functions for trees.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
@@ -544,14 +544,19 @@ make_edges (void)
              switch (cur_region->type)
                {
                case OMP_FOR:
+                 /* Mark all OMP_FOR and OMP_CONTINUE succs edges as abnormal
+                    to prevent splitting them.  */
+                 single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
                  /* Make the loopback edge.  */
-                 make_edge (bb, single_succ (cur_region->entry), 0);
-             
+                 make_edge (bb, single_succ (cur_region->entry),
+                            EDGE_ABNORMAL);
+
                  /* Create an edge from OMP_FOR to exit, which corresponds to
                     the case that the body of the loop is not executed at
                     all.  */
-                 make_edge (cur_region->entry, bb->next_bb, 0);
-                 fallthru = true;
+                 make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
+                 make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
+                 fallthru = false;
                  break;
 
                case OMP_SECTIONS:
index 95c1136..00fbd86 100644 (file)
@@ -1,6 +1,6 @@
 /* Calculate branch probabilities, and basic block execution counts.
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
    based on some ideas from Dain Samples of UC Berkeley.
@@ -419,8 +419,11 @@ static unsigned int
 tree_profiling (void)
 {
   /* Don't profile functions produced at destruction time, particularly
-     the gcov datastructure initializer.  */
-  if (cgraph_state == CGRAPH_STATE_FINISHED)
+     the gcov datastructure initializer.  Don't profile if it has been
+     already instrumented either (when OpenMP expansion creates
+     child function from already instrumented body).  */
+  if (cgraph_state == CGRAPH_STATE_FINISHED
+      || cfun->after_tree_profile)
     return 0;
 
   /* Re-set global shared temporary variable for edge-counters.  */
@@ -441,6 +444,7 @@ tree_profiling (void)
      easy to adjust it, if and when there is some.  */
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);
+  cfun->after_tree_profile = 1;
   return 0;
 }