From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27787 invoked by alias); 23 Jul 2014 09:51:45 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 27729 invoked by uid 89); 23 Jul 2014 09:51:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wg0-f42.google.com Received: from mail-wg0-f42.google.com (HELO mail-wg0-f42.google.com) (74.125.82.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 23 Jul 2014 09:51:40 +0000 Received: by mail-wg0-f42.google.com with SMTP id l18so892240wgh.25 for ; Wed, 23 Jul 2014 02:51:37 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.180.187.6 with SMTP id fo6mr1579943wic.58.1406109097166; Wed, 23 Jul 2014 02:51:37 -0700 (PDT) Received: by 10.195.13.76 with HTTP; Wed, 23 Jul 2014 02:51:37 -0700 (PDT) In-Reply-To: References: Date: Wed, 23 Jul 2014 09:58:00 -0000 Message-ID: Subject: Re: [PATCH, PR61776] verify_flow_info failed: control flow in the middle of basic block with -fprofile-generate From: Richard Biener To: Wei Mi Cc: GCC Patches , Jan Hubicka , David Li , Martin Jambor Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2014-07/txt/msg01504.txt.bz2 On Mon, Jul 21, 2014 at 7:06 PM, Wei Mi wrote: > 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? But fact is that it is _not_ necessary to split the block because there are no outgoing abnormal edges from it. The verifier failure is an artifact from using the same predicates during CFG building and CFG verifying (usually ok, but for this particular case it leads to this issue). So I don't think your patch is the proper way to address this issue (while it certainly works). Instead whether a call can make abnormal gotos should be recorded per-call and stored on the gimple-call. Martin - this is exactly one of the cases your patch would address? Thanks, Richard. > Thanks, > Wei. > > ChangeLog: > > 2014-07-21 Wei Mi > > 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 > > 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 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 > + > +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; > +}