From patchwork Wed May 10 14:20:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 760597 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wNJKy2GWRz9s86 for ; Thu, 11 May 2017 00:20:22 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="nlaWeeV8"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=wWYyOEeF0+7CeDIOGvfeW5FTOpPRFJs3U269P3hXS6APeUYirpCtd bu9/Nyk7AKKJ/xxvxUM90VZaAohS/yNYkthSBY2js9hZsBmTKTKsczPAwP2wLdPk j8KJEud2RJJVxwIwtJagSQzbQ8esDX27xszhs3fTtLKqKC7jq0n78o= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=4rv86tC0dwFRCqtaCsRjTY7FwKA=; b=nlaWeeV8Iyi/jT2nVhM0 Ck2djyi3m7y84fcuHALeBa9SSzefxczU5UH2cygUOLYilwKMgNsmNoo+bHzhBD2H 4NKyfRctMjrxA1ht4gujRE3pwGPkMNg9ol4Muei9LykyG9FCS03AoeVTmFbU6qan DHqlifZuVL0hIM682KzBQDk= Received: (qmail 60151 invoked by alias); 10 May 2017 14:20:09 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 60120 invoked by uid 89); 10 May 2017 14:20:06 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=reliance, NECESSARY X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 10 May 2017 14:20:05 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id E6935AAB2 for ; Wed, 10 May 2017 14:20:05 +0000 (UTC) Date: Wed, 10 May 2017 16:20:05 +0200 (CEST) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Make PRE/FRE elimination not do useless work Message-ID: User-Agent: Alpine 2.20 (LSU 67 2015-01-07) MIME-Version: 1.0 So this is a patch that makes skipping unreachable code when doing elimination possible. Previously interesting interactions with tail-merging made this impossible, now I seem to have figured a way around this. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. With this more elaborate stmt folding during elimination might be in reach. Richard. 2017-05-10 Richard Biener * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Skip unreachable blocks and destinations. (eliminate): Move stmt removal and fixup ... (fini_eliminate): ... here. Skip inserted exprs. (pass_pre::execute): Move fini_pre after fini_eliminate. * tree-ssa-tailmerge.c: Include tree-cfgcleanup.h. (tail_merge_optimize): Run cleanup_tree_cfg if requested by PRE to get rid of dead code that has invalid SSA form and split critical edges again. Index: gcc/tree-ssa-pre.c =================================================================== --- gcc/tree-ssa-pre.c (revision 247831) +++ gcc/tree-ssa-pre.c (working copy) @@ -4196,9 +4196,14 @@ eliminate_dom_walker::before_dom_childre /* Mark new bb. */ el_avail_stack.safe_push (NULL_TREE); - /* ??? If we do nothing for unreachable blocks then this will confuse - tailmerging. Eventually we can reduce its reliance on SCCVN now - that we fully copy/constant-propagate (most) things. */ + /* Skip unreachable blocks marked unreachable during the SCCVN domwalk. */ + edge_iterator ei; + edge e; + FOR_EACH_EDGE (e, ei, b->preds) + if (e->flags & EDGE_EXECUTABLE) + break; + if (! e) + return NULL; for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);) { @@ -4695,10 +4700,8 @@ eliminate_dom_walker::before_dom_childre } /* Replace destination PHI arguments. */ - edge_iterator ei; - edge e; FOR_EACH_EDGE (e, ei, b->succs) - { + if (e->flags & EDGE_EXECUTABLE) for (gphi_iterator gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -4717,7 +4720,6 @@ eliminate_dom_walker::before_dom_childre gimple_set_plf (SSA_NAME_DEF_STMT (sprime), NECESSARY, true); } } - } return NULL; } @@ -4743,9 +4745,6 @@ eliminate_dom_walker::after_dom_children static unsigned int eliminate (bool do_pre) { - gimple_stmt_iterator gsi; - gimple *stmt; - need_eh_cleanup = BITMAP_ALLOC (NULL); need_ab_cleanup = BITMAP_ALLOC (NULL); @@ -4761,6 +4760,18 @@ eliminate (bool do_pre) el_avail.release (); el_avail_stack.release (); + return el_todo; +} + +/* Perform CFG cleanups made necessary by elimination. */ + +static unsigned +fini_eliminate (void) +{ + gimple_stmt_iterator gsi; + gimple *stmt; + unsigned todo = 0; + /* We cannot remove stmts during BB walk, especially not release SSA names there as this confuses the VN machinery. The stmts ending up in el_to_remove are either stores or simple copies. @@ -4782,8 +4793,9 @@ eliminate (bool do_pre) lhs = gimple_get_lhs (stmt); if (inserted_exprs - && TREE_CODE (lhs) == SSA_NAME) - bitmap_clear_bit (inserted_exprs, SSA_NAME_VERSION (lhs)); + && TREE_CODE (lhs) == SSA_NAME + && bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (lhs))) + continue; gsi = gsi_for_stmt (stmt); if (gimple_code (stmt) == GIMPLE_PHI) @@ -4800,7 +4812,7 @@ eliminate (bool do_pre) } /* Removing a stmt may expose a forwarder block. */ - el_todo |= TODO_cleanup_cfg; + todo |= TODO_cleanup_cfg; } el_to_remove.release (); @@ -4819,18 +4831,10 @@ eliminate (bool do_pre) } if (fixup_noreturn_call (stmt)) - el_todo |= TODO_cleanup_cfg; + todo |= TODO_cleanup_cfg; } el_to_fixup.release (); - return el_todo; -} - -/* Perform CFG cleanups made necessary by elimination. */ - -static unsigned -fini_eliminate (void) -{ bool do_eh_cleanup = !bitmap_empty_p (need_eh_cleanup); bool do_ab_cleanup = !bitmap_empty_p (need_ab_cleanup); @@ -4844,8 +4848,8 @@ fini_eliminate (void) BITMAP_FREE (need_ab_cleanup); if (do_eh_cleanup || do_ab_cleanup) - return TODO_cleanup_cfg; - return 0; + todo |= TODO_cleanup_cfg; + return todo; } /* Borrow a bit of tree-ssa-dce.c for the moment. @@ -5110,8 +5114,8 @@ pass_pre::execute (function *fun) remove_dead_inserted_code (); scev_finalize (); - fini_pre (); todo |= fini_eliminate (); + fini_pre (); loop_optimizer_finalize (); /* Restore SSA info before tail-merging as that resets it as well. */ Index: gcc/tree-ssa-tail-merge.c =================================================================== --- gcc/tree-ssa-tail-merge.c (revision 247831) +++ gcc/tree-ssa-tail-merge.c (working copy) @@ -205,6 +205,7 @@ along with GCC; see the file COPYING3. #include "tree-ssa-sccvn.h" #include "cfgloop.h" #include "tree-eh.h" +#include "tree-cfgcleanup.h" /* Describes a group of bbs with the same successors. The successor bbs are cached in succs, and the successor edge flags are cached in succ_flags. @@ -1717,6 +1718,16 @@ tail_merge_optimize (unsigned int todo) timevar_push (TV_TREE_TAIL_MERGE); + /* We enter from PRE which has critical edges split. Elimination + does not process trivially dead code so cleanup the CFG if we + are told so. And re-split critical edges then. */ + if (todo & TODO_cleanup_cfg) + { + cleanup_tree_cfg (); + todo &= ~TODO_cleanup_cfg; + split_critical_edges (); + } + if (!dom_info_available_p (CDI_DOMINATORS)) { /* PRE can leave us with unreachable blocks, remove them now. */