From patchwork Mon Jan 14 15:38:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andi Kleen X-Patchwork-Id: 211810 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 BB6002C0098 for ; Tue, 15 Jan 2013 02:38:56 +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=1358782737; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: From:To:Cc:Subject:Date:Message-Id:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=4YNn7Cn0xf1PKSMpkhfxSGXf758=; b=IzDuQFCV6zZAsfl 7oqfyC84MMLBbfnD2HB8dHOAejHaT5dDWlU8mnS44Q82TJxIaEq7emhnp5YZRRh2 EBY6gLLs0T0N1jshBWrputVfTDKrjrYoQ6jVgbdHPBnnDQC6eFicEiJmWA0HWZ2Z dS1nudCTg08c7Y5MSg5QjN3iVZWo= 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:Received:From:To:Cc:Subject:Date:Message-Id:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=aeUtlc5c7VMt3G20iYWMbd0yqCqPOtoeGz3Ioz4IHL5G7mUzgVPU7NbEp9CRiA vGVtIerOWTdtW1sAFeVLb1/vA1nQ+hJQO8bewB/ezxqMuoZ2AJwNqleqILdYv2X8 86Uzy9cteAtdiMVVFBJmGOK+5aZk4eSYMkM0i77vrjilw=; Received: (qmail 32551 invoked by alias); 14 Jan 2013 15:38:49 -0000 Received: (qmail 32450 invoked by uid 22791); 14 Jan 2013 15:38:48 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from one.firstfloor.org (HELO one.firstfloor.org) (213.235.205.2) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 14 Jan 2013 15:38:38 +0000 Received: from basil.firstfloor.org (71-222-25-158.ptld.qwest.net [71.222.25.158]) by one.firstfloor.org (Postfix) with ESMTP id 115AE1A98073; Mon, 14 Jan 2013 16:38:34 +0100 (CET) Received: by basil.firstfloor.org (Postfix, from userid 1000) id 080A9A20F6; Mon, 14 Jan 2013 07:38:31 -0800 (PST) From: Andi Kleen To: gcc-patches@gcc.gnu.org Cc: ubizjak@gmail.com, Andi Kleen Subject: [PATCH] Let target get_memmodel know about stores/barriers Date: Mon, 14 Jan 2013 07:38:28 -0800 Message-Id: <1358177908-31624-1-git-send-email-andi@firstfloor.org> 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 From: Andi Kleen For HLE stores are only valid with __ATOMIC_HLE_RELEASE. The middle end didn't know this. This adds a new parameter to the get_memmodel target hook to distingush stores and give an warning for acquire stores. I also did a similar check for the barriers where HLE is not useful at all. Fixes one todo in the earlier hle release patch. gcc/: 2013-01-13 Andi Kleen PR target/55948 * builtins.c (get_memmodel): Pass store, barrier parameters to target hook. (expand_builtin_atomic_exchange, expand_builtin_atomic_compare_exchange, expand_builtin_atomic_load, expand_builtin_atomic_store, expand_builtin_atomic_fetch_op, expand_builtin_atomic_test_and_set, expand_builtin_atomic_test_lock, expand_builtin_atomic_clear, expand_builtin_atomic_thread_fence): Pass store, barrier parameters to get_memmodel. * config/i386/i386.c (ix86_memmodel_check): Add store, barrier warning. * doc/tm.texi (TARGET_GET_MEMMODEL): Add store, barrier parameters. * doc/tm.exit.in (TARGET_GET_MEMMODEL): Dito. * target.def (TARGET_GET_MEMMODEL): Dito. --- gcc/builtins.c | 30 +++++++++++++++--------------- gcc/config/i386/i386.c | 21 +++++++++++++++++++-- gcc/doc/tm.texi | 6 ++++-- gcc/doc/tm.texi.in | 4 +++- gcc/target.def | 3 ++- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/gcc/builtins.c b/gcc/builtins.c index 1d0aec6..f9c5656 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5272,10 +5272,12 @@ expand_builtin_sync_lock_release (enum machine_mode mode, tree exp) } /* Given an integer representing an ``enum memmodel'', verify its - correctness and return the memory model enum. */ + correctness and return the memory model enum. When STORE + is true this for a store only. When BARRIER is true this if for + a barrier. */ static enum memmodel -get_memmodel (tree exp) +get_memmodel (tree exp, bool store, bool barrier) { rtx op; unsigned HOST_WIDE_INT val; @@ -5289,7 +5291,7 @@ get_memmodel (tree exp) val = INTVAL (op); if (targetm.memmodel_check) - val = targetm.memmodel_check (val); + val = targetm.memmodel_check (val, store, barrier); else if (val & ~MEMMODEL_MASK) { warning (OPT_Winvalid_memory_model, @@ -5318,7 +5320,7 @@ expand_builtin_atomic_exchange (enum machine_mode mode, tree exp, rtx target) rtx val, mem; enum memmodel model; - model = get_memmodel (CALL_EXPR_ARG (exp, 2)); + model = get_memmodel (CALL_EXPR_ARG (exp, 2), false, false); if ((model & MEMMODEL_MASK) == MEMMODEL_CONSUME) { error ("invalid memory model for %<__atomic_exchange%>"); @@ -5352,8 +5354,8 @@ expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp, tree weak; bool is_weak; - success = get_memmodel (CALL_EXPR_ARG (exp, 4)); - failure = get_memmodel (CALL_EXPR_ARG (exp, 5)); + success = get_memmodel (CALL_EXPR_ARG (exp, 4), false, false); + failure = get_memmodel (CALL_EXPR_ARG (exp, 5), false, false); if ((failure & MEMMODEL_MASK) == MEMMODEL_RELEASE || (failure & MEMMODEL_MASK) == MEMMODEL_ACQ_REL) @@ -5408,7 +5410,7 @@ expand_builtin_atomic_load (enum machine_mode mode, tree exp, rtx target) rtx mem; enum memmodel model; - model = get_memmodel (CALL_EXPR_ARG (exp, 1)); + model = get_memmodel (CALL_EXPR_ARG (exp, 1), false, false); if ((model & MEMMODEL_MASK) == MEMMODEL_RELEASE || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL) { @@ -5437,7 +5439,7 @@ expand_builtin_atomic_store (enum machine_mode mode, tree exp) rtx mem, val; enum memmodel model; - model = get_memmodel (CALL_EXPR_ARG (exp, 2)); + model = get_memmodel (CALL_EXPR_ARG (exp, 2), true, false); if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED && (model & MEMMODEL_MASK) != MEMMODEL_SEQ_CST && (model & MEMMODEL_MASK) != MEMMODEL_RELEASE) @@ -5477,7 +5479,7 @@ expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target, tree fndecl; tree addr; - model = get_memmodel (CALL_EXPR_ARG (exp, 2)); + model = get_memmodel (CALL_EXPR_ARG (exp, 2), false, false); /* Expand the operands. */ mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); @@ -5544,7 +5546,7 @@ expand_builtin_atomic_clear (tree exp) mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0); mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); - model = get_memmodel (CALL_EXPR_ARG (exp, 1)); + model = get_memmodel (CALL_EXPR_ARG (exp, 1), true, false); if ((model & MEMMODEL_MASK) == MEMMODEL_ACQUIRE || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL) @@ -5553,8 +5555,6 @@ expand_builtin_atomic_clear (tree exp) return const0_rtx; } - /* need target hook there to check for not hle acquire */ - if (HAVE_atomic_clear) { emit_insn (gen_atomic_clear (mem, model)); @@ -5585,7 +5585,7 @@ expand_builtin_atomic_test_and_set (tree exp, rtx target) mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0); mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode); - model = get_memmodel (CALL_EXPR_ARG (exp, 1)); + model = get_memmodel (CALL_EXPR_ARG (exp, 1), false, false); return expand_atomic_test_and_set (target, mem, model); } @@ -5724,7 +5724,7 @@ expand_builtin_atomic_is_lock_free (tree exp) static void expand_builtin_atomic_thread_fence (tree exp) { - enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0)); + enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0), false, true); expand_mem_thread_fence (model); } @@ -5735,7 +5735,7 @@ expand_builtin_atomic_thread_fence (tree exp) static void expand_builtin_atomic_signal_fence (tree exp) { - enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0)); + enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0), false, true); expand_mem_signal_fence (model); } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 4f778c1..50b6297 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -42076,14 +42076,31 @@ ix86_destroy_cost_data (void *data) free (data); } -/* Validate target specific memory model bits in VAL. */ +/* Validate target specific memory model bits in VAL. When + STORE is true this for a store. When BARRIER is true + this is for a barrier. */ static unsigned HOST_WIDE_INT -ix86_memmodel_check (unsigned HOST_WIDE_INT val) +ix86_memmodel_check (unsigned HOST_WIDE_INT val, bool store, + bool barrier) { unsigned HOST_WIDE_INT model = val & MEMMODEL_MASK; bool strong; + if (barrier && (val & (IX86_HLE_ACQUIRE|IX86_HLE_RELEASE))) + { + warning (OPT_Winvalid_memory_model, + "__ATOMIC_HLE_ACQUIRE or __ATOMIC_HLE_RELEASE not valid for barriers."); + return MEMMODEL_SEQ_CST; + } + + if (store && (val & IX86_HLE_ACQUIRE)) + { + warning (OPT_Winvalid_memory_model, + "__ATOMIC_HLE_ACQUIRE not valid for stores."); + return MEMMODEL_SEQ_CST; + } + if (val & ~(unsigned HOST_WIDE_INT)(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE |MEMMODEL_MASK) || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE))) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 9d6f6bc..01bc562 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -11338,9 +11338,11 @@ Address Sanitizer shadow memory address. NULL if Address Sanitizer is not supported by the target. @end deftypefn -@deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_MEMMODEL_CHECK (unsigned HOST_WIDE_INT @var{val}) +@deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_MEMMODEL_CHECK (unsigned HOST_WIDE_INT @var{val}, bool @var{store}, bool @var{barrier}) Validate target specific memory model mask bits. When NULL no target specific -memory model bits are allowed. +memory model bits are allowed. When @code{STORE} is true this is for +__atomic_clear or __atomic_store. When @code{BARRIER} is true this is for a +barrier. @end deftypefn @deftypevr {Target Hook} {unsigned char} TARGET_ATOMIC_TEST_AND_SET_TRUEVAL diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 3668882..87f654a 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -11178,7 +11178,9 @@ is zero, which disables this optimization. @hook TARGET_MEMMODEL_CHECK Validate target specific memory model mask bits. When NULL no target specific -memory model bits are allowed. +memory model bits are allowed. When @code{STORE} is true this is for +__atomic_clear or __atomic_store. When @code{BARRIER} is true this is for a +barrier. @end deftypefn @hook TARGET_ATOMIC_TEST_AND_SET_TRUEVAL diff --git a/gcc/target.def b/gcc/target.def index 8627923..46957e9 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2059,7 +2059,8 @@ DEFHOOKPOD DEFHOOK (memmodel_check, "", - unsigned HOST_WIDE_INT, (unsigned HOST_WIDE_INT val), NULL) + unsigned HOST_WIDE_INT, (unsigned HOST_WIDE_INT val, bool store, bool barrier), + NULL) /* Defines an offset bitwise ored into shifted address to get corresponding Address Sanitizer shadow address, or -1 if Address Sanitizer is not