From patchwork Fri Feb 8 00:10:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sriraman Tallam X-Patchwork-Id: 219023 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 0398F2C008C for ; Fri, 8 Feb 2013 11:11:06 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1360887067; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:In-Reply-To:References:Date:Message-ID: Subject:From:To:Cc:Content-Type:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=ygU+p5K3xBmPVmtLY4n1gwN7IVw=; b=jHb+807WWAK9jC1 CS09Rr1orIZ8rIENnHDNWLXEU9+WUJzCB02oKjqOqphlvMJ2rQJtu3G+yvni+r2Z Od81InlDItWckmnFwxHFg7xNdqfQTjBRZnfvuOww9cPO86QK63IQeAQWlykoUW8H N9jYKpjMqmWrz5vWBGZov3H2AJv8= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-Google-DKIM-Signature:MIME-Version:X-Received:Received:In-Reply-To:References:Date:Message-ID:Subject:From:To:Cc:Content-Type:X-Gm-Message-State:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=CGG5Crvitqr4NfeRvIlULHem00uM+Ycv5V/3kwjoVt+3QSBLL7mY3DwerkorFg nrh6BNDoP5GwDLsB/vr0DUVJq6Ab+WMWtw9w0FHrKtUwXcpC2eSXhIbULvOdTbeQ FcBPWkS2CHLINthcmGWpOeO+UZsVqKRUHBtqyhSKleBGA=; Received: (qmail 18174 invoked by alias); 8 Feb 2013 00:10:55 -0000 Received: (qmail 18139 invoked by uid 22791); 8 Feb 2013 00:10:51 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail-oa0-f45.google.com (HELO mail-oa0-f45.google.com) (209.85.219.45) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 08 Feb 2013 00:10:39 +0000 Received: by mail-oa0-f45.google.com with SMTP id o6so3426368oag.4 for ; Thu, 07 Feb 2013 16:10:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type:x-gm-message-state; bh=K4rZ3CnAZoJuyZrgkwOFKu+EOlAnOl8trEOKa2fX4pM=; b=GqAEdaIxP7xrXvWy6ApiMt64ikASfvC56r4SCBIuEqB4t+3mAdvfPnAXU7ZOL/G8Ku mh3Eh+iTQa1VIWRryw4SFwocuTsf8qEBYo4bXcHzISJQcB6IlMv/PUkm26x9pRWZydJi MAftJnBE9jZ8QWnz+Bjy2Lff4f4sjlQbUprHa5vVyWksT0NrVxlYYWQhnxzvbRK9z4dI ZHHy2Un9QwY/km7DASASvfHr4gLdI/ciIFG5QJfznmOjYJTYNqFtOwiHCBrlnRymkeAe qei2iciEm+K8zuGhfSphJvvxLby2/NELGunIJg4ui8DwCFkMQ2Ehmqodm51ZBxzxmQ7P g8HA== MIME-Version: 1.0 X-Received: by 10.60.28.133 with SMTP id b5mr2641789oeh.98.1360282238754; Thu, 07 Feb 2013 16:10:38 -0800 (PST) Received: by 10.182.75.166 with HTTP; Thu, 7 Feb 2013 16:10:38 -0800 (PST) In-Reply-To: <5113BA64.5040709@redhat.com> References: <20130118202236.GE7269@tucnak.redhat.com> <50FAC778.9040702@redhat.com> <20130121143248.GM7269@tucnak.redhat.com> <51092641.7080005@redhat.com> <5113BA64.5040709@redhat.com> Date: Thu, 7 Feb 2013 16:10:38 -0800 Message-ID: Subject: Re: [PATCH] Multiversioning fixes (PR c++/55742, take 2) From: Sriraman Tallam To: Jason Merrill Cc: Jakub Jelinek , Richard Henderson , GCC Patches X-Gm-Message-State: ALoCoQneWf4ygBUTh6soksEIHDzugODXqhevwPHEieKS1EPD65WKD3oxywgzR52DxmzGbftWvcqf8/cUkKA3HN9UkA6RyR9hzebIIQiqs4yGn+uQcojLrieim8hndDLEuX4ckXqn0vHF8pwkeO9oFxDYn+AADesqBcDkm6rsL+EczlwrQrkR1d22/MQxvTFUOZhhNQy8Mj+l X-IsSubscribed: yes 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 On Thu, Feb 7, 2013 at 6:29 AM, Jason Merrill wrote: > On 02/06/2013 08:39 PM, Sriraman Tallam wrote: >> >> +// Test to check if an error is generated when virtual functions >> +// are multiversioned. > > > This seems like a TODO, rather than something to test for. I don't see any > reason why we couldn't support multiversioned virtual functions. > >> error_at (DECL_SOURCE_LOCATION (decl), >> - "Virtual function versioning not supported\n"); >> + "Virtual function multiversioning not supported\n"); > > > And so this should be a sorry rather than an error. Attached a new patch with these changes. Also made more minor changes to config/i386/i386.c. Thanks Sri > > Jason > * doc/extend.texi: Document Function Multiversioning and "default" parameter string to target attribute. * g++.dg/ext/mv12.C: New test. * g++.dg/ext/mv12.h: New file. * g++.dg/ext/mv12-aux.C: New file. * g++.dg/ext/mv13.C: New test. * config/i386/i386.c (get_builtin_code_for_version): Return 0 if target attribute parameter is "default". (ix86_compare_version_priority): Remove checks for target attribute. (ix86_mangle_function_version_assembler_name): Change error to sorry. Remove check for target attribute equal to NULL. Add assert. (ix86_generate_version_dispatcher_body): Change error to sorry. Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 195818) +++ gcc/doc/extend.texi (working copy) @@ -3655,6 +3655,11 @@ Enable/disable the generation of the advanced bit @cindex @code{target("aes")} attribute Enable/disable the generation of the AES instructions. +@item default +@cindex @code{target("default")} attribute +@xref{Function Multiversioning}, where it is used to specify the +default function version. + @item mmx @itemx no-mmx @cindex @code{target("mmx")} attribute @@ -15215,6 +15220,7 @@ Predefined Macros,cpp,The GNU C Preprocessor}). * Bound member functions:: You can extract a function pointer to the method denoted by a @samp{->*} or @samp{.*} expression. * C++ Attributes:: Variable, function, and type attributes for C++ only. +* Function Multiversioning:: Declaring multiple function versions. * Namespace Association:: Strong using-directives for namespace association. * Type Traits:: Compiler support for type traits * Java Exceptions:: Tweaking exception handling to work with Java. @@ -15744,6 +15750,64 @@ interface table mechanism, instead of regular virt See also @ref{Namespace Association}. +@node Function Multiversioning +@section Function Multiversioning +@cindex function versions + +With the GNU C++ front end, for target i386, you may specify multiple +versions of a function, where each function is specialized for a +specific target feature. At runtime, the appropriate version of the +function is automatically executed depending on the characteristics of +the execution platform. Here is an example. + +@smallexample +__attribute__ ((target ("default"))) +int foo () +@{ + // The default version of foo. + return 0; +@} + +__attribute__ ((target ("sse4.2"))) +int foo () +@{ + // foo version for SSE4.2 + return 1; +@} + +__attribute__ ((target ("arch=atom"))) +int foo () +@{ + // foo version for the Intel ATOM processor + return 2; +@} + +__attribute__ ((target ("arch=amdfam10"))) +int foo () +@{ + // foo version for the AMD Family 0x10 processors. + return 3; +@} + +int main () +@{ + int (*p)() = &foo; + assert ((*p) () == foo ()); + return 0; +@} +@end smallexample + +In the above example, four versions of function foo are created. The +first version of foo with the target attribute "default" is the default +version. This version gets executed when no other target specific +version qualifies for execution on a particular platform. A new version +of foo is created by using the same function signature but with a +different target string. Function foo is called or a pointer to it is +taken just like a regular function. GCC takes care of doing the +dispatching to call the right version at runtime. Refer to the +@uref{http://gcc.gnu.org/wiki/FunctionMultiVersioning, GCC wiki on +Function Multiversioning} for more details. + @node Namespace Association @section Namespace Association Index: gcc/testsuite/g++.dg/ext/mv12-aux.C =================================================================== --- gcc/testsuite/g++.dg/ext/mv12-aux.C (revision 0) +++ gcc/testsuite/g++.dg/ext/mv12-aux.C (revision 0) @@ -0,0 +1,11 @@ +// Test case to check if multiversioning works as expected when the versions +// are defined in different files. Auxiliary file for mv12.C. +// { dg-do compile } + +#include "mv12.h" + +__attribute__ ((target ("sse4.2"))) +int foo () +{ + return 1; +} Index: gcc/testsuite/g++.dg/ext/mv12.C =================================================================== --- gcc/testsuite/g++.dg/ext/mv12.C (revision 0) +++ gcc/testsuite/g++.dg/ext/mv12.C (revision 0) @@ -0,0 +1,22 @@ +// Test case to check if multiversioning works as expected when the versions +// are defined in different files. + +// { dg-do run { target i?86-*-* x86_64-*-* } } +// { dg-require-ifunc "" } +// { dg-options "-O2" } +// { dg-additional-sources "mv12-aux.C" } + +#include "mv12.h" + +int main () +{ + if (__builtin_cpu_supports ("sse4.2")) + return foo () - 1; + return foo (); +} + +__attribute__ ((target ("default"))) +int foo () +{ + return 0; +} Index: gcc/testsuite/g++.dg/ext/mv12.h =================================================================== --- gcc/testsuite/g++.dg/ext/mv12.h (revision 0) +++ gcc/testsuite/g++.dg/ext/mv12.h (revision 0) @@ -0,0 +1,6 @@ +// Header file used by mv12.C and mv12-aux.C. +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-options "" } + +int foo () __attribute__ ((target ("default"))); +int foo () __attribute__ ((target ("sse4.2"))); Index: gcc/testsuite/g++.dg/ext/mv13.C =================================================================== --- gcc/testsuite/g++.dg/ext/mv13.C (revision 0) +++ gcc/testsuite/g++.dg/ext/mv13.C (revision 0) @@ -0,0 +1,18 @@ +// Test case to check if multiversioning functions that are extern "C" +// generates errors. + +// { dg-do compile { target i?86-*-* x86_64-*-* } } + +extern "C" +__attribute__ ((target ("default"))) +int foo () // { dg-error "previously defined here" } +{ + return 0; +} + +extern "C" +__attribute__ ((target ("sse4.2"))) +int foo () // { dg-error "redefinition" } +{ + return 1; +} Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 195818) +++ gcc/config/i386/i386.c (working copy) @@ -28695,6 +28695,9 @@ get_builtin_code_for_version (tree decl, tree *pre gcc_assert (TREE_CODE (attrs) == STRING_CST); attrs_str = TREE_STRING_POINTER (attrs); + /* Return priority zero for default function. */ + if (strcmp (attrs_str, "default") == 0) + return 0; /* Handle arch= if specified. For priority, set it to be 1 more than the best instruction set the processor can handle. For instance, if @@ -28827,15 +28830,9 @@ get_builtin_code_for_version (tree decl, tree *pre static int ix86_compare_version_priority (tree decl1, tree decl2) { - unsigned int priority1 = 0; - unsigned int priority2 = 0; + unsigned int priority1 = get_builtin_code_for_version (decl1, NULL); + unsigned int priority2 = get_builtin_code_for_version (decl2, NULL); - if (lookup_attribute ("target", DECL_ATTRIBUTES (decl1)) != NULL) - priority1 = get_builtin_code_for_version (decl1, NULL); - - if (lookup_attribute ("target", DECL_ATTRIBUTES (decl2)) != NULL) - priority2 = get_builtin_code_for_version (decl2, NULL); - return (int)priority1 - (int)priority2; } @@ -29064,14 +29061,12 @@ ix86_mangle_function_version_assembler_name (tree if (DECL_VIRTUAL_P (decl) || DECL_VINDEX (decl)) - error_at (DECL_SOURCE_LOCATION (decl), - "Virtual function versioning not supported\n"); + sorry ("Virtual function multiversioning not supported"); version_attr = lookup_attribute ("target", DECL_ATTRIBUTES (decl)); - /* target attribute string is NULL for default functions. */ - if (version_attr == NULL_TREE) - return id; + /* target attribute string cannot be NULL. */ + gcc_assert (version_attr != NULL_TREE); orig_name = IDENTIFIER_POINTER (id); version_string @@ -29511,8 +29506,8 @@ ix86_generate_version_dispatcher_body (void *node_ virtual methods in base classes but are not explicitly marked as virtual. */ if (DECL_VINDEX (versn->symbol.decl)) - error_at (DECL_SOURCE_LOCATION (versn->symbol.decl), - "Virtual function multiversioning not supported"); + sorry ("Virtual function multiversioning not supported"); + fn_ver_vec.safe_push (versn->symbol.decl); }