From patchwork Sat Dec 6 19:31:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Pinski X-Patchwork-Id: 126062 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9C9A651A431A for ; Sat, 6 Dec 2025 19:34:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9C9A651A431A Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=o3dhWtPF; dkim=pass (2048-bit key, unprotected) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.a=rsa-sha256 header.s=google header.b=EJeJ0R3M X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by sourceware.org (Postfix) with ESMTPS id 32E9A4152BD0 for ; Sat, 6 Dec 2025 19:31:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 32E9A4152BD0 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=oss.qualcomm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oss.qualcomm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 32E9A4152BD0 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1765049499; cv=none; b=GGJlSLUFiVkaaqOcnlZQkp6rjqbPCJaFeSKCAAnT6xo9Uj1lqqj6Chl/+tuW9oMkxG/yF3y2hSMTO5dc1o6Z+e3Kp1Y7jlO77PBtxHvVWSIHsKdbm/AxfMEdiYrJzdj404S6V3s4wFUW+HwiKHq1AOxE7PZ4598knWF85fa/fxI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1765049499; c=relaxed/simple; bh=SDJdfv8TDhv87gMH67n5qNz/SmRGJ1hBemerlaVUg0Y=; h=DKIM-Signature:DKIM-Signature:From:To:Subject:Date:Message-ID: MIME-Version; b=owLRMsXKqgSlNcCIfOPpOkQO4ymehD7JzR811VR7HIH0P0VPKN3mqiHEEAchd18eX8Z/T6l03aFmbtr3phI6JBrO7o/La/4BoreIs0tAgRbdg5cKvo+UVWncMEujo3125+QODL5VYncirN9FlcFgdZKlMf0PwUTQ5j1xEjueOy0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 32E9A4152BD0 Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5B6H1xnB3791133 for ; Sat, 6 Dec 2025 19:31:38 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:message-id:mime-version :subject:to; s=qcppdkim1; bh=bz4wNo7xhSkkzrt7mt6Kr9Jr+qgxxJj60ug e1hQ/ulI=; b=o3dhWtPF079BmtnBLtpUmH2KtAgwCy7VK6jkkj7vHjQSdh+abIQ QR+lZJHupjoXgp1+pzTkwPxHLdlwJrhMPq+vugvV8vRdXB1y4miC8R7JfjWjx4vS Hbw6yDfQ//6YTx9W3nV33EgGtz0cjaYl9YBcs1gDndygjqAIVWC2T70hgonpvNUb OWrijqOEso/MiIlqo8QPByApH63azDdaNosbcYG5JwXvvWkaQu0tnTC6RchzVWEm wPPyWIpy27nqznIbg5GCBSVy4XLV+Ve7NlXO7WKCYWvDkCIzOfu2X7ey7uas+JiY Zj5sa2tOXZoHpzPrhc3n0DgPzO5VbdTHGog== Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4avd8e18he-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Sat, 06 Dec 2025 19:31:37 +0000 (GMT) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-297f8a2ba9eso64477635ad.3 for ; Sat, 06 Dec 2025 11:31:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1765049497; x=1765654297; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=bz4wNo7xhSkkzrt7mt6Kr9Jr+qgxxJj60uge1hQ/ulI=; b=EJeJ0R3MADp04c/KDzYI5cx21ubW99HgIuQ4ruztaDNAvZH4+H7cHryjFNNIyteneG A6N6gceS659XyV+PP15mVbdrHsVHaFhThTjVcSnQwhx8ngsuJe32ze+99LIBtA6vwhHp lC+vqX2HT1TSoX0qw+sqdxODLC+RH2rRKjEH9IJRs1u+q+9ZyJAsGtsYAI7DBakYzzT1 LoDbICMu2U4ZdJ+JD3zT3RtWT92MOp/URPzOGd/jy6IaX/PjJig5uLdpoulGia09Q5k+ sQaMDyeCAq9nXX51N0Za2KxW1NTzkLWP5C28fL733CiH47IhOejoCzrcV0B1SJJ/15Gw zhLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765049497; x=1765654297; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=bz4wNo7xhSkkzrt7mt6Kr9Jr+qgxxJj60uge1hQ/ulI=; b=izjgKco7dhLFMQ+45WSf9d+GYT5+097dVPuJ5sKv9AWg30Ffj/UO7k3ZHIKOCrzBYP cO6e+YwMhwNlPD2iMfSn1xN5IvpYN/RqPc8VZrBZnsFEXNLFpSB7v6nCqwvKPHMo7Xoh wyXDzaLO4Ahw1ipQtkIIiTXzclHHJMzubO9YRndEcgvcQ+F7lT0DqUq4XK/1V8VE4f53 NBATafbXnkGviGt4YFQmlP0CZhHg9ejw6+QiyG5BGuiBG8hSB4EFMvBMawUvYyvnAUFr oey27v7SWhYOgzayOk9x7ZBri18gWo/4ItSpEFsuLKKoB0cboHM3DeF2I8ZHD059MnPN xv2g== X-Gm-Message-State: AOJu0YyM4Jb/Sin10iEpsbfcRxweMUUp27zE/xkMwJOWruN3kbpPu3Ty XZeYF8s7BgJc8Vl6BTObJ9SO0geLdTna74U3uudNN7lLDBb5cq3y/orIFxOJuPlzVvM6pRy4rN/ xDP4Iw9f4mHXzDvg95eIJPxjRJZ/OeeiKY4PVv9pUFrEXkElJutKxqjtS3KKdsi2yR1RJ X-Gm-Gg: ASbGncsvvmyVZEST+bziJOtLjsu3QfTYVJOJ9oZjq0ZTq3tQEIrNbBV6bDAChN9x3be 1ePFniHTuVhHETgebvlHQpK1NVvz6orJd6liG46XfhBFmVaWzeIFiiFI6CUhZxn5vaKijZuV41V /Kw8ogWX5QYa7P/E0Je0YwzWXAcQZotjFZbAs9rU8vnevhCxl0nVyBee845oLFQ2ChzopFsiqvF 6pKDmTb4YY5+IRAhY4dKHEH14iXbxnrLQctIvdFNRC8b29qI+3LlvycHuzsVdo/ygnLgMMD+uY3 CFmsx/5/EQ8vy9NQNrD2d5SE+PL/PD6hPmtwRkP4lB0IO0KLRXU115IZAyi8ELXw1EuANpcImE2 +L8weHbjE6Bctz82Y5ZRJ4P/o+i54UcBlP2mc X-Received: by 2002:a17:903:1670:b0:298:3545:81e2 with SMTP id d9443c01a7336-29df54761aemr34788375ad.22.1765049496816; Sat, 06 Dec 2025 11:31:36 -0800 (PST) X-Google-Smtp-Source: AGHT+IHS43idYTMhNs8mH3mRBnMwywuRvMyqcMAXy6+peTQGyiI9My9rs+5BmW/eXgVq6ZJXdlQLAA== X-Received: by 2002:a17:903:1670:b0:298:3545:81e2 with SMTP id d9443c01a7336-29df54761aemr34788155ad.22.1765049496148; Sat, 06 Dec 2025 11:31:36 -0800 (PST) Received: from xeond2.wrightpinski.org ([98.97.33.108]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-29dae4cf996sm82650035ad.30.2025.12.06.11.31.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 06 Dec 2025 11:31:35 -0800 (PST) From: Andrew Pinski To: gcc-patches@gcc.gnu.org Cc: Andrew Pinski Subject: [PATCH 1/3] cfg: Move make_forwarders_with_degenerate_phis to tree-cfg Date: Sat, 6 Dec 2025 11:31:27 -0800 Message-ID: <20251206193129.3365370-1-andrew.pinski@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjA2MDE2MCBTYWx0ZWRfX+ZpRTvqduaRi 16esA62fhcI3caeEoqxGQVhxPpo+KnXXsEuFyvBcazoGS4UeHNV8DNFbVnSFmXO1FljYDROLzUC KeqlHgHHdMGEkE4M4tgk+LD+0O2zfBy6DbR6s4VUgmre+wMS3qi96QTxkntEaakTf0fhWtWwaVP pLRFvg8OYJYYo992LwtxuJKcjMTSTR2ftGKFaF3fC6KgBFUx7AK2MIbJAGRHQSY5XZ4Z8/hsVKm eUfQBxPZJhIx0hbaclYWf/iRjn218If25XclWkG5G/dzNwalmCAttnQR9/UqpRPHd36SHWF1ak1 NUdYx4+swKMtthM9IijfJXpljXoDjhkI+Dm5Z0viH/Rd6AHf7U/s0Cg5siqrDQBnlZPoMWWTaUL zfQALS9vIL7v10WwCVYLOT9No/LEVg== X-Authority-Analysis: v=2.4 cv=BqaQAIX5 c=1 sm=1 tr=0 ts=69348499 cx=c_pps a=cmESyDAEBpBGqyK7t0alAg==:117 a=m8fSZOrMZksZLhMGLjHzfw==:17 a=wP3pNCr1ah4A:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=A1uBWOOUxzU8vTNse7YA:9 a=1OuFwYUASf3TG4hYMiVC:22 a=-Xo0g-rXMuVevE6R1laq:22 X-Proofpoint-GUID: 0lyZAkQdeY9HIg6RMZPGtdJIYa1YCBe1 X-Proofpoint-ORIG-GUID: 0lyZAkQdeY9HIg6RMZPGtdJIYa1YCBe1 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-12-06_02,2025-12-04_04,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 phishscore=0 spamscore=0 lowpriorityscore=0 impostorscore=0 adultscore=0 priorityscore=1501 bulkscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512060160 X-Spam-Status: No, score=-18.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org This moves make_forwarders_with_degenerate_phis to tree-cfg.cc from tree-ssa-dce.cc to be able to use in a different pass. Bootstrapped and tested on x86_64-linux-gnu. gcc/ChangeLog: * tree-ssa-dce.cc (sort_phi_args): Move to tree-cfg.cc. (make_forwarders_with_degenerate_phis): Move to tree-cfg.cc. (perform_tree_ssa_dce): Update for the updated return type of make_forwarders_with_degenerate_phis. * tree-cfg.cc (sort_phi_args): Moved from tree-ssa-dce.cc. (make_forwarders_with_degenerate_phis): Moved from tree-ssa-dce.cc. Update return type to bool and return true if an edge was split. * tree-cfg.h (make_forwarders_with_degenerate_phis): New decl. Signed-off-by: Andrew Pinski --- gcc/tree-cfg.cc | 211 +++++++++++++++++++++++++++++++++++++++++++ gcc/tree-cfg.h | 1 + gcc/tree-ssa-dce.cc | 212 +------------------------------------------- 3 files changed, 214 insertions(+), 210 deletions(-) diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 1d20e6ab6ba..243740e8e21 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -10173,6 +10173,217 @@ make_pass_fixup_cfg (gcc::context *ctxt) return new pass_fixup_cfg (ctxt); } + +/* Sort PHI argument values for make_forwarders_with_degenerate_phis. */ + +static int +sort_phi_args (const void *a_, const void *b_) +{ + auto *a = (const std::pair *) a_; + auto *b = (const std::pair *) b_; + hashval_t ha = a->second; + hashval_t hb = b->second; + if (ha < hb) + return -1; + else if (ha > hb) + return 1; + else if (a->first->dest_idx < b->first->dest_idx) + return -1; + else if (a->first->dest_idx > b->first->dest_idx) + return 1; + else + return 0; +} + +/* Look for a non-virtual PHIs and make a forwarder block when all PHIs + have the same argument on a set of edges. This is to not consider + control dependences of individual edges for same values but only for + the common set. Returns true if changed the CFG. */ + +bool +make_forwarders_with_degenerate_phis (function *fn) +{ + bool didsomething = false; + + basic_block bb; + FOR_EACH_BB_FN (bb, fn) + { + /* Only PHIs with three or more arguments have opportunities. */ + if (EDGE_COUNT (bb->preds) < 3) + continue; + /* Do not touch loop headers or blocks with abnormal predecessors. + ??? This is to avoid creating valid loops here, see PR103458. + We might want to improve things to either explicitely add those + loops or at least consider blocks with no backedges. */ + if (bb->loop_father->header == bb + || bb_has_abnormal_pred (bb)) + continue; + + /* Take one PHI node as template to look for identical + arguments. Build a vector of candidates forming sets + of argument edges with equal values. Note optimality + depends on the particular choice of the template PHI + since equal arguments are unordered leaving other PHIs + with more than one set of equal arguments within this + argument range unsorted. We'd have to break ties by + looking at other PHI nodes. */ + gphi_iterator gsi = gsi_start_nonvirtual_phis (bb); + if (gsi_end_p (gsi)) + continue; + gphi *phi = gsi.phi (); + auto_vec, 8> args; + bool need_resort = false; + for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) + { + edge e = gimple_phi_arg_edge (phi, i); + /* Skip abnormal edges since we cannot redirect them. */ + if (e->flags & EDGE_ABNORMAL) + continue; + /* Skip loop exit edges when we are in loop-closed SSA form + since the forwarder we'd create does not have a PHI node. */ + if (loops_state_satisfies_p (LOOP_CLOSED_SSA) + && loop_exit_edge_p (e->src->loop_father, e)) + continue; + + tree arg = gimple_phi_arg_def (phi, i); + if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME) + need_resort = true; + args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0))); + } + if (args.length () < 2) + continue; + args.qsort (sort_phi_args); + /* The above sorting can be different between -g and -g0, as e.g. decls + can have different uids (-g could have bigger gaps in between them). + So, only use that to determine which args are equal, then change + second from hash value to smallest dest_idx of the edges which have + equal argument and sort again. If all the phi arguments are + constants or SSA_NAME, there is no need for the second sort, the hash + values are stable in that case. */ + hashval_t hash = args[0].second; + args[0].second = args[0].first->dest_idx; + bool any_equal = false; + for (unsigned i = 1; i < args.length (); ++i) + if (hash == args[i].second + && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first), + PHI_ARG_DEF_FROM_EDGE (phi, args[i].first))) + { + args[i].second = args[i - 1].second; + any_equal = true; + } + else + { + hash = args[i].second; + args[i].second = args[i].first->dest_idx; + } + if (!any_equal) + continue; + if (need_resort) + args.qsort (sort_phi_args); + + /* From the candidates vector now verify true candidates for + forwarders and create them. */ + gphi *vphi = get_virtual_phi (bb); + unsigned start = 0; + while (start < args.length () - 1) + { + unsigned i; + for (i = start + 1; i < args.length (); ++i) + if (args[start].second != args[i].second) + break; + /* args[start]..args[i-1] are equal. */ + if (start != i - 1) + { + /* Check all PHI nodes for argument equality + except for vops. */ + bool equal = true; + gphi_iterator gsi2 = gsi; + gsi_next (&gsi2); + for (; !gsi_end_p (gsi2); gsi_next (&gsi2)) + { + gphi *phi2 = gsi2.phi (); + if (virtual_operand_p (gimple_phi_result (phi2))) + continue; + tree start_arg + = PHI_ARG_DEF_FROM_EDGE (phi2, args[start].first); + for (unsigned j = start + 1; j < i; ++j) + { + if (!operand_equal_p (start_arg, + PHI_ARG_DEF_FROM_EDGE + (phi2, args[j].first))) + { + /* Another PHI might have a shorter set of + equivalent args. Go for that. */ + i = j; + if (j == start + 1) + equal = false; + break; + } + } + if (!equal) + break; + } + if (equal) + { + /* If we are asked to forward all edges the block + has all degenerate PHIs. Do nothing in that case. */ + if (start == 0 + && i == args.length () + && args.length () == gimple_phi_num_args (phi)) + break; + /* Instead of using make_forwarder_block we are + rolling our own variant knowing that the forwarder + does not need PHI nodes apart from eventually + a virtual one. */ + auto_vec vphi_args; + if (vphi) + { + vphi_args.reserve_exact (i - start); + for (unsigned j = start; j < i; ++j) + vphi_args.quick_push + (PHI_ARG_DEF_FROM_EDGE (vphi, args[j].first)); + } + free_dominance_info (fn, CDI_DOMINATORS); + basic_block forwarder = split_edge (args[start].first); + profile_count count = profile_count::zero (); + bool irr = false; + for (unsigned j = start + 1; j < i; ++j) + { + edge e = args[j].first; + if (e->flags & EDGE_IRREDUCIBLE_LOOP) + irr = true; + redirect_edge_and_branch_force (e, forwarder); + redirect_edge_var_map_clear (e); + count += e->count (); + } + forwarder->count = count; + if (irr) + { + forwarder->flags |= BB_IRREDUCIBLE_LOOP; + single_succ_edge (forwarder)->flags + |= EDGE_IRREDUCIBLE_LOOP; + } + + if (vphi) + { + tree def = copy_ssa_name (vphi_args[0]); + gphi *vphi_copy = create_phi_node (def, forwarder); + for (unsigned j = start; j < i; ++j) + add_phi_arg (vphi_copy, vphi_args[j - start], + args[j].first, UNKNOWN_LOCATION); + SET_PHI_ARG_DEF + (vphi, single_succ_edge (forwarder)->dest_idx, def); + } + didsomething = true; + } + } + /* Continue searching for more opportunities. */ + start = i; + } + } + return didsomething; +} + /* Garbage collection support for edge_def. */ extern void gt_ggc_mx (tree&); diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h index 520bb3aefbd..2e01762f04b 100644 --- a/gcc/tree-cfg.h +++ b/gcc/tree-cfg.h @@ -114,6 +114,7 @@ extern edge gimple_switch_edge (function *, gswitch *, unsigned); extern edge gimple_switch_default_edge (function *, gswitch *); extern bool cond_only_block_p (basic_block); extern void copy_phi_arg_into_existing_phi (edge, edge, bool = false); +extern bool make_forwarders_with_degenerate_phis (function *); /* Return true if the LHS of a call should be removed. */ diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc index 317a0d6179b..9a9f6f93fce 100644 --- a/gcc/tree-ssa-dce.cc +++ b/gcc/tree-ssa-dce.cc @@ -1940,214 +1940,6 @@ tree_dce_done (bool aggressive) worklist.release (); } -/* Sort PHI argument values for make_forwarders_with_degenerate_phis. */ - -static int -sort_phi_args (const void *a_, const void *b_) -{ - auto *a = (const std::pair *) a_; - auto *b = (const std::pair *) b_; - hashval_t ha = a->second; - hashval_t hb = b->second; - if (ha < hb) - return -1; - else if (ha > hb) - return 1; - else if (a->first->dest_idx < b->first->dest_idx) - return -1; - else if (a->first->dest_idx > b->first->dest_idx) - return 1; - else - return 0; -} - -/* Look for a non-virtual PHIs and make a forwarder block when all PHIs - have the same argument on a set of edges. This is to not consider - control dependences of individual edges for same values but only for - the common set. */ - -static unsigned -make_forwarders_with_degenerate_phis (function *fn) -{ - unsigned todo = 0; - - basic_block bb; - FOR_EACH_BB_FN (bb, fn) - { - /* Only PHIs with three or more arguments have opportunities. */ - if (EDGE_COUNT (bb->preds) < 3) - continue; - /* Do not touch loop headers or blocks with abnormal predecessors. - ??? This is to avoid creating valid loops here, see PR103458. - We might want to improve things to either explicitely add those - loops or at least consider blocks with no backedges. */ - if (bb->loop_father->header == bb - || bb_has_abnormal_pred (bb)) - continue; - - /* Take one PHI node as template to look for identical - arguments. Build a vector of candidates forming sets - of argument edges with equal values. Note optimality - depends on the particular choice of the template PHI - since equal arguments are unordered leaving other PHIs - with more than one set of equal arguments within this - argument range unsorted. We'd have to break ties by - looking at other PHI nodes. */ - gphi_iterator gsi = gsi_start_nonvirtual_phis (bb); - if (gsi_end_p (gsi)) - continue; - gphi *phi = gsi.phi (); - auto_vec, 8> args; - bool need_resort = false; - for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) - { - edge e = gimple_phi_arg_edge (phi, i); - /* Skip abnormal edges since we cannot redirect them. */ - if (e->flags & EDGE_ABNORMAL) - continue; - /* Skip loop exit edges when we are in loop-closed SSA form - since the forwarder we'd create does not have a PHI node. */ - if (loops_state_satisfies_p (LOOP_CLOSED_SSA) - && loop_exit_edge_p (e->src->loop_father, e)) - continue; - - tree arg = gimple_phi_arg_def (phi, i); - if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME) - need_resort = true; - args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0))); - } - if (args.length () < 2) - continue; - args.qsort (sort_phi_args); - /* The above sorting can be different between -g and -g0, as e.g. decls - can have different uids (-g could have bigger gaps in between them). - So, only use that to determine which args are equal, then change - second from hash value to smallest dest_idx of the edges which have - equal argument and sort again. If all the phi arguments are - constants or SSA_NAME, there is no need for the second sort, the hash - values are stable in that case. */ - hashval_t hash = args[0].second; - args[0].second = args[0].first->dest_idx; - bool any_equal = false; - for (unsigned i = 1; i < args.length (); ++i) - if (hash == args[i].second - && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first), - PHI_ARG_DEF_FROM_EDGE (phi, args[i].first))) - { - args[i].second = args[i - 1].second; - any_equal = true; - } - else - { - hash = args[i].second; - args[i].second = args[i].first->dest_idx; - } - if (!any_equal) - continue; - if (need_resort) - args.qsort (sort_phi_args); - - /* From the candidates vector now verify true candidates for - forwarders and create them. */ - gphi *vphi = get_virtual_phi (bb); - unsigned start = 0; - while (start < args.length () - 1) - { - unsigned i; - for (i = start + 1; i < args.length (); ++i) - if (args[start].second != args[i].second) - break; - /* args[start]..args[i-1] are equal. */ - if (start != i - 1) - { - /* Check all PHI nodes for argument equality. */ - bool equal = true; - gphi_iterator gsi2 = gsi; - gsi_next (&gsi2); - for (; !gsi_end_p (gsi2); gsi_next (&gsi2)) - { - gphi *phi2 = gsi2.phi (); - if (virtual_operand_p (gimple_phi_result (phi2))) - continue; - tree start_arg - = PHI_ARG_DEF_FROM_EDGE (phi2, args[start].first); - for (unsigned j = start + 1; j < i; ++j) - { - if (!operand_equal_p (start_arg, - PHI_ARG_DEF_FROM_EDGE - (phi2, args[j].first))) - { - /* Another PHI might have a shorter set of - equivalent args. Go for that. */ - i = j; - if (j == start + 1) - equal = false; - break; - } - } - if (!equal) - break; - } - if (equal) - { - /* If we are asked to forward all edges the block - has all degenerate PHIs. Do nothing in that case. */ - if (start == 0 - && i == args.length () - && args.length () == gimple_phi_num_args (phi)) - break; - /* Instead of using make_forwarder_block we are - rolling our own variant knowing that the forwarder - does not need PHI nodes apart from eventually - a virtual one. */ - auto_vec vphi_args; - if (vphi) - { - vphi_args.reserve_exact (i - start); - for (unsigned j = start; j < i; ++j) - vphi_args.quick_push - (PHI_ARG_DEF_FROM_EDGE (vphi, args[j].first)); - } - free_dominance_info (fn, CDI_DOMINATORS); - basic_block forwarder = split_edge (args[start].first); - profile_count count = profile_count::zero (); - bool irr = false; - for (unsigned j = start + 1; j < i; ++j) - { - edge e = args[j].first; - if (e->flags & EDGE_IRREDUCIBLE_LOOP) - irr = true; - redirect_edge_and_branch_force (e, forwarder); - redirect_edge_var_map_clear (e); - count += e->count (); - } - forwarder->count = count; - if (irr) - { - forwarder->flags |= BB_IRREDUCIBLE_LOOP; - single_succ_edge (forwarder)->flags - |= EDGE_IRREDUCIBLE_LOOP; - } - - if (vphi) - { - tree def = copy_ssa_name (vphi_args[0]); - gphi *vphi_copy = create_phi_node (def, forwarder); - for (unsigned j = start; j < i; ++j) - add_phi_arg (vphi_copy, vphi_args[j - start], - args[j].first, UNKNOWN_LOCATION); - SET_PHI_ARG_DEF - (vphi, single_succ_edge (forwarder)->dest_idx, def); - } - todo |= TODO_cleanup_cfg; - } - } - /* Continue searching for more opportunities. */ - start = i; - } - } - return todo; -} /* Main routine to eliminate dead code. @@ -2174,8 +1966,8 @@ perform_tree_ssa_dce (bool aggressive) scev_initialize (); } - if (aggressive) - todo |= make_forwarders_with_degenerate_phis (cfun); + if (aggressive && make_forwarders_with_degenerate_phis (cfun)) + todo |= TODO_cleanup_cfg; calculate_dominance_info (CDI_DOMINATORS);