From patchwork Tue Sep 20 16:43:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Agostino Vitillo X-Patchwork-Id: 115601 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]) by ozlabs.org (Postfix) with SMTP id 928B1B70BE for ; Wed, 21 Sep 2011 02:43:52 +1000 (EST) Received: (qmail 28141 invoked by alias); 20 Sep 2011 16:43:42 -0000 Received: (qmail 27849 invoked by uid 22791); 20 Sep 2011 16:43:36 -0000 X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_OV, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-gx0-f175.google.com (HELO mail-gx0-f175.google.com) (209.85.161.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 20 Sep 2011 16:43:15 +0000 Received: by gxk4 with SMTP id 4so526324gxk.20 for ; Tue, 20 Sep 2011 09:43:14 -0700 (PDT) Received: by 10.42.145.137 with SMTP id f9mr1839568icv.128.1316536994158; Tue, 20 Sep 2011 09:43:14 -0700 (PDT) Received: from [192.168.1.133] (c-24-130-86-79.hsd1.ca.comcast.net. [24.130.86.79]) by mx.google.com with ESMTPS id el2sm2843954ibb.10.2011.09.20.09.43.12 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 20 Sep 2011 09:43:13 -0700 (PDT) From: Roberto Agostino Vitillo Subject: devirtualize final virtual function calls Date: Tue, 20 Sep 2011 09:43:13 -0700 Message-Id: Cc: jason@redhat.com, Paolo Carlini , Vincenzo Innocente To: gcc-patches@gcc.gnu.org Mime-Version: 1.0 (Apple Message framework v1244.3) 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 When calling a final virtual function or a virtual function that belongs to a final class there is no need for a virtual lookup. E.g.: struct A final { virtual void foo () { } }; struct B { virtual void foo () final { } }; void fun(A* a, B* b) { a->foo(); b->foo(); } with this patch translates to: (__TEXT,__text) section __Z3funP1AP1B: 0000000000000000 pushq %rbp 0000000000000001 movq %rsp,%rbp 0000000000000004 subq $0x10,%rsp 0000000000000008 movq %rdi,0xf8(%rbp) 000000000000000c movq %rsi,0xf0(%rbp) 0000000000000010 movq 0xf8(%rbp),%rax 0000000000000014 movq %rax,%rdi 0000000000000017 callq __ZN1A3fooEv 000000000000001c movq 0xf0(%rbp),%rax 0000000000000020 movq %rax,%rdi 0000000000000023 callq __ZN1B3fooEv 0000000000000028 leave 0000000000000029 ret Tested on macosx x86_64. r 2011-09-20 Roberto Agostino Vitillo * gcc/testsuite/g++.dg/other/final1.C: new test * gcc/cp/call.c (build_new_method_call_1): use non virtual lookup for final virtual functions Index: gcc/testsuite/g++.dg/other/final1.C =================================================================== --- gcc/testsuite/g++.dg/other/final1.C (revision 0) +++ gcc/testsuite/g++.dg/other/final1.C (revision 0) @@ -0,0 +1,26 @@ +/* Verify that final methods are devirtualized */ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-original -std=c++0x" } */ + +struct A final +{ + virtual void foo () + { + } +}; + +struct B +{ + virtual void foo () final + { + } +}; + +void fun(A* a, B* b) +{ + a->foo(); + b->foo(); +} + +/* { dg-final { scan-tree-dump-times "A::foo" 2 "original" } } */ +/* { dg-final { scan-tree-dump-times "B::foo" 2 "original" } } */ Index: gcc/cp/call.c =================================================================== --- gcc/cp/call.c (revision 178911) +++ gcc/cp/call.c (working copy) @@ -7277,8 +7277,9 @@ } else { - if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL) - && resolves_to_fixed_type_p (instance, 0)) + if (DECL_VINDEX (fn) && ((! (flags & LOOKUP_NONVIRTUAL) + && resolves_to_fixed_type_p (instance, 0)) + || DECL_FINAL_P (fn) || CLASSTYPE_FINAL (basetype))) flags |= LOOKUP_NONVIRTUAL; if (explicit_targs) flags |= LOOKUP_EXPLICIT_TMPL_ARGS;