public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, PR61776] verify_flow_info failed: control flow in the middle of basic block with -fprofile-generate
@ 2014-07-21 18:21 Wei Mi
  2014-07-21 18:21 ` Wei Mi
  2014-07-23  9:58 ` Richard Biener
  0 siblings, 2 replies; 10+ messages in thread
From: Wei Mi @ 2014-07-21 18:21 UTC (permalink / raw)
  To: GCC Patches; +Cc: Richard Biener, Jan Hubicka, David Li

Hi,

This patch is to fix:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61776

It records func decls whose const/pure flags are reset during
instrumentation. After the loop resetting const/pure flags, find out
stmts calling those recorded funcs and perform cfg fixup on them.

bootstrap and regression test pass on x86_64-linux-gnu. ok for trunk
and gcc-4_9?

Thanks,
Wei.

ChangeLog:

2014-07-21  Wei Mi  <wmi@google.com>

        PR middle-end/61776
        * tree-profile.c (tree_profiling): Fix cfg after the const/pure
        flags of some funcs are reset after instrumentation.

2014-07-21  Wei Mi  <wmi@google.com>

        PR middle-end/61776
        * testsuite/gcc.dg/pr61776.c: New test.

Index: tree-profile.c
===================================================================
--- tree-profile.c      (revision 212442)
+++ tree-profile.c      (working copy)
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.
 #include "target.h"
 #include "tree-cfgcleanup.h"
 #include "tree-nested.h"
+#include "pointer-set.h"

 static GTY(()) tree gcov_type_node;
 static GTY(()) tree tree_interval_profiler_fn;
@@ -562,6 +563,9 @@ static unsigned int
 tree_profiling (void)
 {
   struct cgraph_node *node;
+  int i;
+  struct pointer_set_t *modified_constpure_decls;
+  vec<gimple> modified_constpure_stmts;

   /* This is a small-ipa pass that gets called only once, from
      cgraphunit.c:ipa_passes().  */
@@ -603,6 +607,9 @@ tree_profiling (void)
       pop_cfun ();
     }

+  modified_constpure_decls = pointer_set_create ();
+  modified_constpure_stmts.create (0);
+
   /* Drop pure/const flags from instrumented functions.  */
   FOR_EACH_DEFINED_FUNCTION (node)
     {
@@ -615,6 +622,11 @@ tree_profiling (void)
       if (DECL_SOURCE_LOCATION (node->decl) == BUILTINS_LOCATION)
        continue;

+      /* If the const/pure flag of node is about to change, record
+        node->decl in modified_constpure_decls.  */
+      if (DECL_PURE_P (node->decl) || TREE_READONLY (node->decl))
+       pointer_set_insert (modified_constpure_decls, node->decl);
+
       cgraph_set_const_flag (node, false, false);
       cgraph_set_pure_flag (node, false, false);
     }
@@ -623,6 +635,7 @@ tree_profiling (void)
   FOR_EACH_DEFINED_FUNCTION (node)
     {
       basic_block bb;
+      gimple stmt;

       if (!gimple_has_body_p (node->decl)
          || !(!node->clone_of
@@ -642,10 +655,29 @@ tree_profiling (void)
            {
              gimple stmt = gsi_stmt (gsi);
              if (is_gimple_call (stmt))
-               update_stmt (stmt);
+               {
+                 tree decl = gimple_call_fndecl(stmt);
+                 if (decl && pointer_set_contains (modified_constpure_decls,
+                                                   decl))
+                   modified_constpure_stmts.safe_push (stmt);
+                 update_stmt (stmt);
+               }
            }
        }

+      /* The const/pure flag of the decl of call stmt in
modified_constpure_stmts
+        is changed because of instrumentation. Split block if the
call stmt is not
+        the last stmt of bb and the call stmt ends bb.  */
+      FOR_EACH_VEC_ELT (modified_constpure_stmts, i, stmt)
+       {
+         basic_block bb = gimple_bb (stmt);
+
+         if (stmt != gsi_stmt (gsi_last_bb (bb))
+             && stmt_ends_bb_p (stmt))
+           split_block (bb, stmt);
+       }
+      modified_constpure_stmts.release ();
+
       /* re-merge split blocks.  */
       cleanup_tree_cfg ();
       update_ssa (TODO_update_ssa);
@@ -657,6 +689,7 @@ tree_profiling (void)

   handle_missing_profiles ();

+  pointer_set_destroy (modified_constpure_decls);
   del_node_map ();
   return 0;
 }
Index: testsuite/gcc.dg/pr61776.c
===================================================================
--- testsuite/gcc.dg/pr61776.c  (revision 0)
+++ testsuite/gcc.dg/pr61776.c  (revision 0)
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fprofile-generate" } */
+
+#include <setjmp.h>
+
+int cond1, cond2;
+
+int goo() __attribute__((noinline));
+
+int goo() {
+ if (cond1)
+   return 1;
+ else
+   return 2;
+}
+
+jmp_buf env;
+int foo() {
+ int a;
+
+ setjmp(env);
+ if (cond2)
+   a = goo();
+ else
+   a = 3;
+ return a;
+}

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-08-20 14:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-21 18:21 [PATCH, PR61776] verify_flow_info failed: control flow in the middle of basic block with -fprofile-generate Wei Mi
2014-07-21 18:21 ` Wei Mi
2014-07-23  9:58 ` Richard Biener
2014-07-23 12:48   ` Martin Jambor
2014-07-23 13:47     ` Richard Biener
2014-07-28  6:40   ` Wei Mi
2014-08-12 20:56     ` Wei Mi
2014-08-14 14:32     ` Richard Biener
2014-08-19 18:46       ` Wei Mi
2014-08-20 14:18         ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).