On Mon, Jun 19, 2023 at 9:52 AM Jan Hubicka via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > Hi, > this was suggested earlier somewhere, but I can not find the thread. > C++ has assume attribute that expands int > if (conditional) > __builtin_unreachable () > We do not want to account the conditional in inline heuristics since > we know that it is going to be optimized out. > > Bootstrapped/regtested x86_64-linux, will commit it later today if > thre are no complains.
I think we also had the request to not account the condition feeding stmts (if they only feed it and have no side-effects). libstdc++ has complex range comparisons here. Also ... > gcc/ChangeLog: > > * ipa-fnsummary.cc (builtin_unreachable_bb_p): New function. > (analyze_function_body): Do not account conditionals guarding > builtin_unreachable calls. > > gcc/testsuite/ChangeLog: > > * gcc.dg/ipa/fnsummary-1.c: New test. > > diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc > index a5f5a50c8a5..987da29ec34 100644 > --- a/gcc/ipa-fnsummary.cc > +++ b/gcc/ipa-fnsummary.cc > @@ -2649,6 +2649,54 @@ points_to_possible_sra_candidate_p (tree t) > return false; > } > > +/* Return true if BB is builtin_unreachable. > + We skip empty basic blocks, debug statements, clobbers and predicts. > + CACHE is used to memoize already analyzed blocks. */ > + > +static bool > +builtin_unreachable_bb_p (basic_block bb, vec<unsigned char> &cache) > +{ > + if (cache[bb->index]) > + return cache[bb->index] - 1; > + gimple_stmt_iterator si; > + auto_vec <basic_block, 4> visited_bbs; > + bool ret = false; > + while (true) > + { > + bool empty_bb = true; > + visited_bbs.safe_push (bb); > + cache[bb->index] = 3; > + for (si = gsi_start_nondebug_bb (bb); > + !gsi_end_p (si) && empty_bb; > + gsi_next_nondebug (&si)) > + { > + if (gimple_code (gsi_stmt (si)) != GIMPLE_PREDICT > + && !gimple_clobber_p (gsi_stmt (si)) > + && !gimple_nop_p (gsi_stmt (si))) > + { > + empty_bb = false; > + break; > + } > + } > + if (!empty_bb) > + break; > + else > + bb = single_succ_edge (bb)->dest; > + if (cache[bb->index]) > + { > + ret = cache[bb->index] == 3 ? false : cache[bb->index] - 1; > + goto done; > + } > + } > + if (gimple_call_builtin_p (gsi_stmt (si), BUILT_IN_UNREACHABLE) > + || gimple_call_builtin_p (gsi_stmt (si), BUILT_IN_UNREACHABLE_TRAP)) ... we do code generate BUILT_IN_UNREACHABLE_TRAP, no? > + ret = true; > +done: > + for (basic_block vbb:visited_bbs) > + cache[vbb->index] = (unsigned char)ret + 1; > + return ret; > +} > + > /* Analyze function body for NODE. > EARLY indicates run from early optimization pipeline. */ > > @@ -2743,6 +2791,8 @@ analyze_function_body (struct cgraph_node *node, bool > early) > const profile_count entry_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count; > order = XNEWVEC (int, n_basic_blocks_for_fn (cfun)); > nblocks = pre_and_rev_post_order_compute (NULL, order, false); > + auto_vec<unsigned char, 10> cache; > + cache.safe_grow_cleared (last_basic_block_for_fn (cfun)); A sbitmap with two bits per entry would be more space efficient here. bitmap has bitmap_set_aligned_chunk and bitmap_get_aligned_chunk for convenience, adding the corresponding to sbitmap.h would likely ease use there as well. > for (n = 0; n < nblocks; n++) > { > bb = BASIC_BLOCK_FOR_FN (cfun, order[n]); > @@ -2901,6 +2951,24 @@ analyze_function_body (struct cgraph_node *node, bool > early) > } > } > > + /* Conditionals guarding __builtin_unreachable will be > + optimized out. */ > + if (gimple_code (stmt) == GIMPLE_COND) > + { > + edge_iterator ei; > + edge e; > + FOR_EACH_EDGE (e, ei, bb->succs) > + if (builtin_unreachable_bb_p (e->dest, cache)) > + { > + if (dump_file) > + fprintf (dump_file, > + "\t\tConditional guarding > __builtin_unreachable; ignored\n"); > + this_time = 0; > + this_size = 0; > + break; > + } > + } > + > /* TODO: When conditional jump or switch is known to be constant, > but > we did not translate it into the predicates, we really can > account > just maximum of the possible paths. */ > diff --git a/gcc/testsuite/gcc.dg/ipa/fnsummary-1.c > b/gcc/testsuite/gcc.dg/ipa/fnsummary-1.c > new file mode 100644 > index 00000000000..a0ece0c300b > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/ipa/fnsummary-1.c > @@ -0,0 +1,8 @@ > +/* { dg-options "-O2 -fdump-ipa-fnsummary" } */ > +int > +test(int a) > +{ > + if (a > 10) > + __builtin_unreachable (); > +} > +/* { dg-final { scan-ipa-dump "Conditional guarding __builtin_unreachable" > "fnsummary" } } */