From patchwork Sat Aug 9 22:09:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 378814 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 554471400AB for ; Sun, 10 Aug 2014 08:09:45 +1000 (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=DxYGxXjTDGSHQq0bWNM/XzixLcmDzelh4Fdu+PA5o1QxFG1rN18tc d0eYoPMyyWjzls9L/zUuqmfqFo14BleQYeUq1zWeyFbtZp2SWtW2yq4VLZ8krsPi OjmwTNmoJDXVS76KDGVfk70fSyTNnHn1MN3Hz8rBoZw7/5ozUta3/o= 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=htJHg4aY5ln4d+g8OBJ47wYjFs0=; b=tqWqgJHnDDybcqVschW6 aZdtSMXt+L8vsn6lFCKTiX/FOpVh4EqAXrUEh8TAmIHjdcjpYZz0MABx07s2yB8U ADmgWRdBhXFEbyHQao3ZpankT1q6X42E3TXpziVO3hysc54K2ZtoLReCTP3eBkZa FvzESYXUynUo2L9yaoD0uo8= Received: (qmail 5992 invoked by alias); 9 Aug 2014 22:09:35 -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 5980 invoked by uid 89); 9 Aug 2014 22:09:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sat, 09 Aug 2014 22:09:31 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id AA1E3540E1E; Sun, 10 Aug 2014 00:09:27 +0200 (CEST) Date: Sun, 10 Aug 2014 00:09:27 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Fix side case in ipa-devirt Message-ID: <20140809220927.GA12548@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi, tree-ssa-pre is checking that new dynamic type detection (get_dynamic_type) catch all cases as old. Firefox has somewhat obscure case when new code runs into placement new paranoia earlier. This patch fixes it and also fixes templates of last two testcases that had unresolved tests. * g++.dg/ipa/devirt-35.C: Fix template. * g++.dg/ipa/devirt-36.C: Likewise. * g++.dg/ipa/devirt-37.C: New testcase. * ipa-devirt.c (get_dynamic_type): Handle case when instance is in DECL correctly; do not give up on types in static storage. Index: testsuite/g++.dg/ipa/devirt-35.C =================================================================== --- testsuite/g++.dg/ipa/devirt-35.C (revision 213757) +++ testsuite/g++.dg/ipa/devirt-35.C (working copy) @@ -15,9 +15,9 @@ m(struct B *b) // test2 may change the type of A by placement new. // C++ standard is bit imprecise about this. } -/* { dg-final { scan-ipa-dump "converting indirect call to function virtual int B::t" "fre1" } } */ +/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t" "fre1" } } */ /* { dg-final { scan-ipa-dump "to virtual int B::t" "devirt" } } */ /* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */ /* { dg-final { cleanup-ipa-dump "devirt" } } */ -/* { dg-final { cleanup-tree-dump "fre" } } */ +/* { dg-final { cleanup-tree-dump "fre1" } } */ Index: testsuite/g++.dg/ipa/devirt-37.C =================================================================== --- testsuite/g++.dg/ipa/devirt-37.C (revision 0) +++ testsuite/g++.dg/ipa/devirt-37.C (revision 0) @@ -0,0 +1,35 @@ +/* { dg-options "-fpermissive -fno-indirect-inlining -fno-devirtualize-speculatively -fdump-tree-fre2-details" } */ +#include +struct A {virtual void test() {abort ();}}; +struct B:A + {virtual void test() {} + B(); + B(void (*test)(struct A *));}; + +void extcall(void); + +inline void tt(struct A *a) +{ + a->test(); +} + +B::B (void (*test)(struct A *)) +{ + struct B c; + struct A *a=this; + extcall(); + test(a); +} +void +t() +{ + struct B b(tt); +} +/* After inlining the call within constructor needs to be checked to not go into a basetype. + We should see the vtbl store and we should notice extcall as possibly clobbering the + type but ignore it because b is in static storage. */ +/* { dg-final { scan-tree-dump "Determined dynamic type." "fre2" } } */ +/* { dg-final { scan-tree-dump "Checking vtbl store:" "fre2" } } */ +/* { dg-final { scan-tree-dump "Function call may change dynamic type:extcall" "fre2" } } */ +/* { dg-final { scan-tree-dump "converting indirect call to function virtual void" "fre2" } } */ +/* { dg-final { cleanup-tree-dump "fre2" } } */ Index: testsuite/g++.dg/ipa/devirt-36.C =================================================================== --- testsuite/g++.dg/ipa/devirt-36.C (revision 213757) +++ testsuite/g++.dg/ipa/devirt-36.C (working copy) @@ -17,9 +17,9 @@ m(struct B *b) // test2 may change the type of A by placement new. // C++ standard is bit imprecise about this. } -/* { dg-final { scan-ipa-dump "converting indirect call to function virtual int B::t" "fre1" } } */ +/* { dg-final { scan-tree-dump "converting indirect call to function virtual int B::t" "fre1" } } */ /* { dg-final { scan-ipa-dump "to virtual int B::t" "devirt" } } */ /* { dg-final { scan-ipa-dump "1 speculatively devirtualized" "devirt" } } */ /* { dg-final { cleanup-ipa-dump "devirt" } } */ -/* { dg-final { cleanup-tree-dump "fre" } } */ +/* { dg-final { cleanup-tree-dump "fre1" } } */ Index: ipa-devirt.c =================================================================== --- ipa-devirt.c (revision 213757) +++ ipa-devirt.c (working copy) @@ -2799,10 +2799,12 @@ get_dynamic_type (tree instance, /* Finally verify that what we found looks like read from OTR_OBJECT or from INSTANCE with offset OFFSET. */ if (base_ref - && TREE_CODE (base_ref) == MEM_REF - && ((offset2 == context->offset - && TREE_OPERAND (base_ref, 0) == instance) - || (!offset2 && TREE_OPERAND (base_ref, 0) == otr_object))) + && ((TREE_CODE (base_ref) == MEM_REF + && ((offset2 == context->offset + && TREE_OPERAND (base_ref, 0) == instance) + || (!offset2 && TREE_OPERAND (base_ref, 0) == otr_object))) + || (DECL_P (instance) && base_ref == instance + && offset2 == context->offset))) { stmt = SSA_NAME_DEF_STMT (ref); instance_ref = ref_exp; @@ -2923,7 +2925,14 @@ get_dynamic_type (tree instance, && !function_entry_reached && !tci.multiple_types_encountered) { - if (!tci.speculative) + if (!tci.speculative + /* Again in instances located in static storage we are interested only + in constructor stores. */ + || (context->outer_type + && !tci.seen_unanalyzed_store + && context->offset == tci.offset + && types_same_for_odr (tci.known_current_type, + context->outer_type))) { context->outer_type = tci.known_current_type; context->offset = tci.known_current_offset;