From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id 9367838618DB; Thu, 28 Sep 2023 13:14:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9367838618DB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1695906885; bh=i7a7R6nM//vGkjGPiKlaPH70TezevV0D3sixUdebdNE=; h=From:To:Subject:Date:From; b=G8mGMCHsaEgHTd/WjSutq09j+/P+ZjGEgHocmAg5sbO5VM2eJ1+ywiYf2NlX0+cFr T/dFTbmMwBlBOROw4ExdIbThRXv4m8qjordfX0oqVS0PpWOl08CGUHaU9JTUVAEnpL G6TyLJS5rOCE6e3UM/ky0zv0W+LIO7eAOUHvygzA= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-4308] target/111600 - avoid deep recursion in access diagnostics X-Act-Checkin: gcc X-Git-Author: Richard Biener X-Git-Refname: refs/heads/master X-Git-Oldrev: 4f41d497c9eeec6f97a5c240e03c7e5e1a1ec05e X-Git-Newrev: f194c684a28a5d449bd034a2c604d04ba465e4fe Message-Id: <20230928131445.9367838618DB@sourceware.org> Date: Thu, 28 Sep 2023 13:14:45 +0000 (GMT) List-Id: https://gcc.gnu.org/g:f194c684a28a5d449bd034a2c604d04ba465e4fe commit r14-4308-gf194c684a28a5d449bd034a2c604d04ba465e4fe Author: Richard Biener Date: Thu Sep 28 11:51:30 2023 +0200 target/111600 - avoid deep recursion in access diagnostics pass_waccess::check_dangling_stores uses recursion to traverse the CFG. The following changes this to use a heap allocated worklist to avoid blowing the stack. Instead of using a better iteration order it tries hard to preserve the current iteration order to avoid new false positives to pop up since the set of stores we keep track isn't properly modeling flow, so what is diagnosed and what not is quite random. We are also lacking the ideal RPO compute on the inverted graph that would just ignore reverse unreachable code (as the current iteration scheme does). PR target/111600 * gimple-ssa-warn-access.cc (pass_waccess::check_dangling_stores): Use a heap allocated worklist for CFG traversal instead of recursion. Diff: --- gcc/gimple-ssa-warn-access.cc | 51 +++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index ac07a6f9b95..fcaff128d60 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -2141,7 +2141,7 @@ private: void check_dangling_uses (tree, tree, bool = false, bool = false); void check_dangling_uses (); void check_dangling_stores (); - void check_dangling_stores (basic_block, hash_set &, auto_bitmap &); + bool check_dangling_stores (basic_block, hash_set &); void warn_invalid_pointer (tree, gimple *, gimple *, tree, bool, bool = false); @@ -4524,17 +4524,13 @@ pass_waccess::check_dangling_uses (tree var, tree decl, bool maybe /* = false */ /* Diagnose stores in BB and (recursively) its predecessors of the addresses of local variables into nonlocal pointers that are left dangling after - the function returns. BBS is a bitmap of basic blocks visited. */ + the function returns. Returns true when we can continue walking + the CFG to predecessors. */ -void +bool pass_waccess::check_dangling_stores (basic_block bb, - hash_set &stores, - auto_bitmap &bbs) + hash_set &stores) { - if (!bitmap_set_bit (bbs, bb->index)) - /* Avoid cycles. */ - return; - /* Iterate backwards over the statements looking for a store of the address of a local variable into a nonlocal pointer. */ for (auto gsi = gsi_last_nondebug_bb (bb); ; gsi_prev_nondebug (&gsi)) @@ -4550,7 +4546,7 @@ pass_waccess::check_dangling_stores (basic_block bb, && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))) /* Avoid looking before nonconst, nonpure calls since those might use the escaped locals. */ - return; + return false; if (!is_gimple_assign (stmt) || gimple_clobber_p (stmt) || !gimple_store_p (stmt)) @@ -4576,7 +4572,7 @@ pass_waccess::check_dangling_stores (basic_block bb, gimple *def_stmt = SSA_NAME_DEF_STMT (lhs_ref.ref); if (!gimple_nop_p (def_stmt)) /* Avoid looking at or before stores into unknown objects. */ - return; + return false; lhs_ref.ref = SSA_NAME_VAR (lhs_ref.ref); } @@ -4620,13 +4616,7 @@ pass_waccess::check_dangling_stores (basic_block bb, } } - edge e; - edge_iterator ei; - FOR_EACH_EDGE (e, ei, bb->preds) - { - basic_block pred = e->src; - check_dangling_stores (pred, stores, bbs); - } + return true; } /* Diagnose stores of the addresses of local variables into nonlocal @@ -4635,9 +4625,32 @@ pass_waccess::check_dangling_stores (basic_block bb, void pass_waccess::check_dangling_stores () { + if (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (m_func)->preds) == 0) + return; + auto_bitmap bbs; hash_set stores; - check_dangling_stores (EXIT_BLOCK_PTR_FOR_FN (m_func), stores, bbs); + auto_vec worklist (n_basic_blocks_for_fn (cfun) + 1); + worklist.quick_push (ei_start (EXIT_BLOCK_PTR_FOR_FN (m_func)->preds)); + do + { + edge_iterator ei = worklist.last (); + basic_block src = ei_edge (ei)->src; + if (bitmap_set_bit (bbs, src->index)) + { + if (check_dangling_stores (src, stores) + && EDGE_COUNT (src->preds) > 0) + worklist.quick_push (ei_start (src->preds)); + } + else + { + if (ei_one_before_end_p (ei)) + worklist.pop (); + else + ei_next (&worklist.last ()); + } + } + while (!worklist.is_empty ()); } /* Check for and diagnose uses of dangling pointers to auto objects