diff options
author | Richard Biener <rguenther@suse.de> | 2022-08-19 15:11:14 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2022-08-30 10:05:38 +0200 |
commit | f71abacfed170852ab25485e5c52f8d5aad7c2a0 (patch) | |
tree | aa71d253d28d289d9948a9c85fd066ccceda1a2f | |
parent | bfaa6807defb18874e4c4b6b8608fe0afee7d7b8 (diff) | |
download | gcc-f71abacfed170852ab25485e5c52f8d5aad7c2a0.zip gcc-f71abacfed170852ab25485e5c52f8d5aad7c2a0.tar.gz gcc-f71abacfed170852ab25485e5c52f8d5aad7c2a0.tar.bz2 |
Use reachability analysis to improve uninit diagnostic
This patch does what the comment in uninit diagnostic suggests.
When the value-numbering run done without optimizing figures there's
a fallthru path, consider blocks on it as always executed.
* tree-ssa-uninit.cc (warn_uninitialized_vars): Pre-compute
the set of fallthru reachable blocks from function entry
and use that to determine wlims.always_executed.
-rw-r--r-- | gcc/tree-ssa-uninit.cc | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/gcc/tree-ssa-uninit.cc b/gcc/tree-ssa-uninit.cc index 0bd567f..c25fbe6 100644 --- a/gcc/tree-ssa-uninit.cc +++ b/gcc/tree-ssa-uninit.cc @@ -988,10 +988,43 @@ warn_uninitialized_vars (bool wmaybe_uninit) wlimits wlims = { }; wlims.wmaybe_uninit = wmaybe_uninit; - gimple_stmt_iterator gsi; - basic_block bb; + auto_bb_flag ft_reachable (cfun); + + /* Mark blocks that are always executed when we ignore provably + not executed edges. */ + basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + while (!(bb->flags & ft_reachable)) + { + bb->flags |= ft_reachable; + /* Find a single executable edge. */ + edge_iterator ei; + edge e, ee = NULL; + FOR_EACH_EDGE (e, ei, bb->succs) + if (e->flags & EDGE_EXECUTABLE) + { + if (!ee) + ee = e; + else + { + ee = NULL; + break; + } + } + if (ee) + bb = ee->dest; + else + { + bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb); + if (!bb || bb->index == EXIT_BLOCK) + break; + } + } + FOR_EACH_BB_FN (bb, cfun) { + wlims.always_executed = (bb->flags & ft_reachable); + bb->flags &= ~ft_reachable; + edge_iterator ei; edge e; FOR_EACH_EDGE (e, ei, bb->preds) @@ -1002,14 +1035,10 @@ warn_uninitialized_vars (bool wmaybe_uninit) if (!e) continue; - basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); - /* ??? This could be improved when we use a greedy walk and have - some edges marked as not executable. */ - wlims.always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb); - if (wlims.always_executed) warn_uninit_phi_uses (bb); + gimple_stmt_iterator gsi; for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple *stmt = gsi_stmt (gsi); @@ -1030,7 +1059,7 @@ warn_uninitialized_vars (bool wmaybe_uninit) FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE) { /* BIT_INSERT_EXPR first operand should not be considered - a use for the purpose of uninit warnings. */ + a use for the purpose of uninit warnings. */ if (gassign *ass = dyn_cast <gassign *> (stmt)) { if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR @@ -1041,7 +1070,7 @@ warn_uninitialized_vars (bool wmaybe_uninit) if (wlims.always_executed) warn_uninit (OPT_Wuninitialized, use, SSA_NAME_VAR (use), stmt); - else if (wmaybe_uninit) + else if (wlims.wmaybe_uninit) warn_uninit (OPT_Wmaybe_uninitialized, use, SSA_NAME_VAR (use), stmt); } |