From patchwork Sun Aug 25 15:19:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 269706 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "www.sourceware.org", Issuer "StartCom Class 1 Primary Intermediate Server CA" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 96AEF2C00AC for ; Mon, 26 Aug 2013 01:19:39 +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=QcTknkj57qFDuOAwyWDPP6pD6N7MDTx0zj3aMpe6mbCPLoe5wWJ+X TBnMQz0sRiFh28pqdGuo9ycftRuzUIBoFGI8SbDjfuRBymEKe1u5SVpmGkeUoPUr L1rHP5efX0OTfV5INh55faWubX6PYYXjN4XsIuJkMtIduZIyxYzMdM= 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=nalVqMrS5blq5RUhd3nM2wujsdc=; b=SToE5CcT8cVvOl23Lp+K LhwT4fvWpZVsk2VllzWVhsiIgWvTk/DCpijQG2G7pCx1XAI+ZB9PN7hafn9xA9rR Em5DGjKbHXh1XNhW3hLO6zr3Lj18Xo/kTaA50UdBL1RLcuJBTAQ1Z4C2tYvAoFux QaAYh0vf/NkE33JoWFohwBs= Received: (qmail 8760 invoked by alias); 25 Aug 2013 15:19:31 -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 8750 invoked by uid 89); 25 Aug 2013 15:19:31 -0000 X-Spam-SWARE-Status: No, score=-5.2 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RP_MATCHES_RCVD autolearn=ham version=3.3.2 Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with (AES256-SHA encrypted) ESMTPS; Sun, 25 Aug 2013 15:19:29 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id E40A4541EF9; Sun, 25 Aug 2013 17:19:24 +0200 (CEST) Date: Sun, 25 Aug 2013 17:19:24 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Handle final types & methods in ipa-devirt Message-ID: <20130825151924.GA29339@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Hi, this patch adds ipa-devirt code for final types and methods. There is probably no way to construct a testcase that will be devirtualized, since all the simple minded devirtualization is already done by FE. I however checked that dumps seems sane at least. Once we are able to track types of THIS pointers, this will become interesting. Bootstrapped/regtested x86_64-linux, will commit it shortly. Honza * ipa-devirt.c (struct odr_type_d): Add final_type field. (dump_odr_type): Add dumping. (possible_polymorphic_call_targets): Support final types and final methods. Index: ipa-devirt.c =================================================================== --- ipa-devirt.c (revision 201974) +++ ipa-devirt.c (working copy) @@ -137,6 +137,8 @@ struct GTY(()) odr_type_d int id; /* Is it in anonymous namespace? */ bool anonymous_namespace; + /* Is it final type? */ + bool final_type; }; @@ -270,6 +272,7 @@ get_odr_type (tree type, bool insert) val->bases = vNULL; val->derived_types = vNULL; val->anonymous_namespace = type_in_anonymous_namespace_p (type); + val->final_type = TYPE_FINAL_P (type); *slot = val; for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++) /* For now record only polymorphic types. other are @@ -300,7 +303,8 @@ dump_odr_type (FILE *f, odr_type t, int unsigned int i; fprintf (f, "%*s type %i: ", indent * 2, "", t->id); print_generic_expr (f, t->type, TDF_SLIM); - fprintf (f, "%s\n", t->anonymous_namespace ? " (anonymous namespace)":""); + fprintf (f, "%s%s\n", t->anonymous_namespace ? " (anonymous namespace)":"", + t->final_type ? " (final)":""); if (TYPE_NAME (t->type)) { fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "", @@ -598,7 +602,7 @@ possible_polymorphic_call_targets (tree /* For anonymous namespace types we can attempt to build full type. All derivations must be in this unit. */ - if (type->anonymous_namespace && finalp && !flag_ltrans) + if ((type->anonymous_namespace || type->final_type) && finalp && !flag_ltrans) *finalp = true; /* Initialize query cache. */ @@ -637,19 +641,24 @@ possible_polymorphic_call_targets (tree target = gimple_get_virt_method_for_binfo (otr_token, binfo); if (target) maybe_record_node (nodes, target, inserted); - pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo)); - /* TODO: If method is final, we can stop here and signaize that - list is final. We need C++ FE to pass our info about final - methods and classes. */ + /* If we failed to find the method, we no longer have final list + This can happen i.e. when we can not refer to decl from other unit. */ + if (!nodes.length()) + *finalp = false; + pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo)); - /* Walk recursively all derived types. Here we need to lookup proper basetype - via their BINFO walk that is done by record_binfo */ - for (i = 0; i < type->derived_types.length(); i++) - possible_polymorphic_call_targets_1 (nodes, inserted, - matched_vtables, - otr_type, type->derived_types[i], - otr_token); + /* If method is not final, walk recursively all derived types. + Here we need to lookup proper basetype via their BINFO walk that is done + by record_binfo */ + if (!nodes.length () || !DECL_FINAL_P (nodes[0]->symbol.decl)) + for (i = 0; i < type->derived_types.length(); i++) + possible_polymorphic_call_targets_1 (nodes, inserted, + matched_vtables, + otr_type, type->derived_types[i], + otr_token); + else if (finalp) + *finalp = true; (*slot)->targets = nodes; pointer_set_destroy (inserted);