From patchwork Fri Oct 10 11:03:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 398516 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 B5B471400BE for ; Fri, 10 Oct 2014 22:07:34 +1100 (EST) 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=X+232LbtrLzjj3vawtKtPEhNWwRuRBeVeZKSIL2qMKvBGFYi3iGye W6FzaG+n2hJF51vme5c1+SuPLGa8ruTHU9tobEuaT4xzHJpTalrYRSsLbEdk0+Bn 97ZB65ztGunXEZKqtoxvtkfBwVwWcsgrPw2cDO0uYY1Aw20d1vOgHU= 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=lXYN2kla07VmKLl5hLbTj2gT4GA=; b=SKOVGD4UCFQIYOUn3F83 GyDkT2/UWaBlpL1YipupYKu1l+4A/D8jpsySEwZ7DR54vaXW0PMjRorScmT5JnYd M//eL7s1FbDfvXFU9e1n5VJBxiZ2gRWYAACs0BN8758NHblk/z1y/tTO5bks5Xzc XKQqdHIq0GRn70N9C1WD3+Y= Received: (qmail 22059 invoked by alias); 10 Oct 2014 11:07:28 -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 22049 invoked by uid 89); 10 Oct 2014 11:07:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.7 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Fri, 10 Oct 2014 11:07:26 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 76698AB07 for ; Fri, 10 Oct 2014 11:07:23 +0000 (UTC) Date: Fri, 10 Oct 2014 13:03:29 +0200 (CEST) From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix PR63476 Message-ID: User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 This fixes PRE not keeping virtual SSA form up-to-date during insertion and thus eventual VOP walks from the devirt code during elimination. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2014-10-10 Richard Biener PR tree-optimization/63476 * tree-ssa-pre.c (struct bb_bitmap_sets): Add vop_on_exit member. (BB_LIVE_VOP_ON_EXIT): New define. (create_expression_by_pieces): Assign VUSEs to stmts. (compute_avail): Track BB_LIVE_VOP_ON_EXIT. (pass_pre::execute): Assert virtual SSA form is up-to-date after insertion. * g++.dg/torture/pr63476.C: New testcase. Index: gcc/tree-ssa-pre.c =================================================================== --- gcc/tree-ssa-pre.c (revision 216037) +++ gcc/tree-ssa-pre.c (working copy) @@ -423,6 +423,9 @@ typedef struct bb_bitmap_sets /* A cache for value_dies_in_block_x. */ bitmap expr_dies; + /* The live virtual operand on successor edges. */ + tree vop_on_exit; + /* True if we have visited this block during ANTIC calculation. */ unsigned int visited : 1; @@ -440,6 +443,7 @@ typedef struct bb_bitmap_sets #define EXPR_DIES(BB) ((bb_value_sets_t) ((BB)->aux))->expr_dies #define BB_VISITED(BB) ((bb_value_sets_t) ((BB)->aux))->visited #define BB_MAY_NOTRETURN(BB) ((bb_value_sets_t) ((BB)->aux))->contains_may_not_return_call +#define BB_LIVE_VOP_ON_EXIT(BB) ((bb_value_sets_t) ((BB)->aux))->vop_on_exit /* Basic block list in postorder. */ @@ -2886,12 +2890,15 @@ create_expression_by_pieces (basic_block bitmap_value_replace_in_set (NEW_SETS (block), nameexpr); bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr); } + + gimple_set_vuse (stmt, BB_LIVE_VOP_ON_EXIT (block)); } gimple_seq_add_seq (stmts, forced_stmts); } name = make_temp_ssa_name (exprtype, NULL, "pretmp"); newstmt = gimple_build_assign (name, folded); + gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block)); gimple_set_plf (newstmt, NECESSARY, false); gimple_seq_add_stmt (stmts, newstmt); @@ -3593,6 +3623,9 @@ compute_avail (void) son = next_dom_son (CDI_DOMINATORS, son)) worklist[sp++] = son; + BB_LIVE_VOP_ON_EXIT (ENTRY_BLOCK_PTR_FOR_FN (cfun)) + = ssa_default_def (cfun, gimple_vop (cfun)); + /* Loop until the worklist is empty. */ while (sp) { @@ -3607,7 +3640,10 @@ compute_avail (void) its immediate dominator. */ dom = get_immediate_dominator (CDI_DOMINATORS, block); if (dom) - bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom)); + { + bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom)); + BB_LIVE_VOP_ON_EXIT (block) = BB_LIVE_VOP_ON_EXIT (dom); + } /* Generate values for PHI nodes. */ for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -3617,7 +3653,10 @@ compute_avail (void) /* We have no need for virtual phis, as they don't represent actual computations. */ if (virtual_operand_p (result)) - continue; + { + BB_LIVE_VOP_ON_EXIT (block) = result; + continue; + } pre_expr e = get_or_alloc_expr_for_name (result); add_to_value (get_expr_value_id (e), e); @@ -3661,6 +3700,9 @@ compute_avail (void) bitmap_value_insert_into_set (AVAIL_OUT (block), e); } + if (gimple_vdef (stmt)) + BB_LIVE_VOP_ON_EXIT (block) = gimple_vdef (stmt); + if (gimple_has_side_effects (stmt) || stmt_could_throw_p (stmt) || is_gimple_debug (stmt)) @@ -4758,6 +4794,10 @@ pass_pre::execute (function *fun) remove_fake_exit_edges (); gsi_commit_edge_inserts (); + /* Eliminate folds statements which might (should not...) end up + not keeping virtual operands up-to-date. */ + gcc_assert (!need_ssa_update_p (fun)); + /* Remove all the redundant expressions. */ todo |= eliminate (true); Index: gcc/testsuite/g++.dg/torture/pr63476.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr63476.C (revision 0) +++ gcc/testsuite/g++.dg/torture/pr63476.C (working copy) @@ -0,0 +1,39 @@ +// { dg-do compile } +// { dg-additional-options "-std=gnu++11" } + +enum class nsresult; +class A; +class B +{ +public: + B (int); + A *operator->(); +}; +class C +{ +}; +class A +{ +public: + virtual nsresult AddObserver (const char *, C *, bool) = 0; +}; +class D : A +{ + nsresult + AddObserver (const char *p1, C *p2, bool p3) + { + AddObserver (p1, p2, p3); + } +}; +char *prefList[]{}; +class F : C +{ + nsresult Install (); +}; +nsresult +F::Install () +{ + B branch = 0; + for (int i;;) + branch->AddObserver (prefList[i], this, false); +}