This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Validate the HLE memory models.
- From: Andi Kleen <andi at firstfloor dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: kirill dot yukhin at gmail dot com, triegel at redhat dot com, amacleod at redhat dot com, jakub at redhat dot com, ubizjak at gmail dot com, hjl dot tools at gmail dot com, Andi Kleen <ak at linux dot intel dot com>
- Date: Wed, 25 Apr 2012 01:29:10 -0700
- Subject: [PATCH] Validate the HLE memory models.
From: Andi Kleen <ak@linux.intel.com>
This is on top of Kirill's latest patch.
Based on the earlier discussion. Warn and enforce reasonable memory models
for HLE ACQUIRE and RELEASE. It's not useful to have a weaker compiler
memory model than what the CPU implements for a transaction.
With HLE_ACQUIRE model must be ACQUIRE or stronger. With HLE_RELEASE model must
be RELEASE or stronger.
I implemented this with a new target hook that replaces the target variable
originally added in the earlier patch.
Passes bootstrap and test suite on x86_64-linux
gcc/:
2012-04-24 Andi Kleen <ak@linux.intel.com>
* builtins.c (get_memmodel): Add val. Call target.memmodel_check
and return new variable.
* config/i386/i386.c (ix86_memmodel_check): Add.
(TARGET_MEMMODEL_MASK): Replace with TARGET_MEMMODEL_CHECK.
* doc/tm.texi (TARGET_MEMMODEL_MASK): Replace with TARGET_MEMMODEL_CHECK..
* doc/tm.texi.in (TARGET_MEMMODEL_MASK): Replace with TARGET_MEMMODEL_CHECK.
* target.def (memmodel_mask): Replace with memmodel_check.
---
gcc/builtins.c | 8 ++++++--
gcc/config/i386/i386.c | 35 +++++++++++++++++++++++++++++++++--
gcc/doc/tm.texi | 7 ++++---
gcc/doc/tm.texi.in | 7 ++++---
gcc/target.def | 6 +++---
5 files changed, 50 insertions(+), 13 deletions(-)
diff --git a/gcc/builtins.c b/gcc/builtins.c
index bd66ff0..8f25086 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5338,6 +5338,7 @@ static enum memmodel
get_memmodel (tree exp)
{
rtx op;
+ int val;
/* If the parameter is not a constant, it's a run time value so we'll just
convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking. */
@@ -5346,7 +5347,10 @@ get_memmodel (tree exp)
op = expand_normal (exp);
- if(INTVAL (op) & ~(MEMMODEL_MASK | targetm.memmodel_mask))
+ val = INTVAL (op);
+ if (targetm.memmodel_check)
+ val = targetm.memmodel_check (val);
+ else if (val & ~MEMMODEL_MASK)
{
warning (OPT_Winvalid_memory_model,
"Unknown architecture specifier in memory model to builtin.");
@@ -5361,7 +5365,7 @@ get_memmodel (tree exp)
return MEMMODEL_SEQ_CST;
}
- return (enum memmodel) INTVAL (op);
+ return (enum memmodel) val;
}
/* Expand the __atomic_exchange intrinsic:
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0b6d6be..d17fcac 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -38967,6 +38967,37 @@ ix86_autovectorize_vector_sizes (void)
return (TARGET_AVX && !TARGET_PREFER_AVX128) ? 32 | 16 : 0;
}
+/* Validate target specific memory model bits in VAL. */
+
+static unsigned int
+ix86_memmodel_check (unsigned val)
+{
+ unsigned model = val & MEMMODEL_MASK;
+ int strong;
+
+ if (val & ~(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE|MEMMODEL_MASK)
+ || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE)))
+ {
+ warning (OPT_Winvalid_memory_model,
+ "Unknown architecture specific memory model");
+ return MEMMODEL_SEQ_CST;
+ }
+ strong = (model == MEMMODEL_ACQ_REL || model == MEMMODEL_SEQ_CST);
+ if (val & IX86_HLE_ACQUIRE && !(model == MEMMODEL_ACQUIRE || strong))
+ {
+ warning (OPT_Winvalid_memory_model,
+ "HLE_ACQUIRE not used with ACQUIRE or stronger memory model");
+ return MEMMODEL_SEQ_CST | IX86_HLE_ACQUIRE;
+ }
+ if (val & IX86_HLE_RELEASE && !(model == MEMMODEL_RELEASE || strong))
+ {
+ warning (OPT_Winvalid_memory_model,
+ "HLE_RELEASE not used with RELEASE or stronger memory model");
+ return MEMMODEL_SEQ_CST | IX86_HLE_RELEASE;
+ }
+ return val;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
@@ -39066,8 +39097,8 @@ ix86_autovectorize_vector_sizes (void)
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
-#undef TARGET_MEMMODEL_MASK
-#define TARGET_MEMMODEL_MASK (IX86_HLE_ACQUIRE|IX86_HLE_RELEASE)
+#undef TARGET_MEMMODEL_CHECK
+#define TARGET_MEMMODEL_CHECK ix86_memmodel_check
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index ee0d700..4c57a9c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11362,9 +11362,10 @@ MIPS, where add-immediate takes a 16-bit signed value,
@code{TARGET_CONST_ANCHOR} is set to @samp{0x8000}. The default value
is zero, which disables this optimization. @end deftypevr
-@deftypevr {Target Hook} {unsigned HOST_WIDE_INT} TARGET_MEMMODEL_MASK
-Some architectures may prvide additional memory model bits. This hook
-must mask such a bits. @end deftypevr
+@deftypefn {Target Hook} unsigned TARGET_MEMMODEL_CHECK (unsigned @var{val})
+Validate target specific memory model mask bits. When NULL no target specific
+memory model bits are allowed.
+@end deftypefn
@deftypevr {Target Hook} {unsigned char} TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
This value should be set if the result written by @code{atomic_test_and_set} is not exactly 1, i.e. the @code{bool} @code{true}.
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 95eef59..af76e7b 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -11242,8 +11242,9 @@ MIPS, where add-immediate takes a 16-bit signed value,
@code{TARGET_CONST_ANCHOR} is set to @samp{0x8000}. The default value
is zero, which disables this optimization. @end deftypevr
-@hook TARGET_MEMMODEL_MASK
-Some architectures may prvide additional memory model bits. This hook
-must mask such a bits. @end deftypevr
+@hook TARGET_MEMMODEL_CHECK
+Validate target specific memory model mask bits. When NULL no target specific
+memory model bits are allowed.
+@end deftypefn
@hook TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
diff --git a/gcc/target.def b/gcc/target.def
index f06b6bf..1d74893 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1941,10 +1941,10 @@ DEFHOOKPOD
unsigned HOST_WIDE_INT, 0)
/* Defines, which target-dependent bits (upper 16) are used by port */
-DEFHOOKPOD
-(memmodel_mask,
+DEFHOOK
+(memmodel_check,
"",
- unsigned HOST_WIDE_INT, 0)
+ unsigned, (unsigned val), NULL)
/* Functions relating to calls - argument passing, returns, etc. */
/* Members of struct call have no special macro prefix. */
--
1.7.7.6