Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-29 Thread Rainer Orth
Hi Martin,

> 2016-09-06  Martin Liska  
>
>   * gcc.dg/profile-update-warning.c: New test.
[...]
> diff --git a/gcc/testsuite/gcc.dg/profile-update-warning.c 
> b/gcc/testsuite/gcc.dg/profile-update-warning.c
> new file mode 100644
> index 000..0614fad
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/profile-update-warning.c
> @@ -0,0 +1,7 @@
> +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
> +/* { dg-options "-fprofile-update=atomic -fprofile-generate -march=i386 
> -m32" } */
> +
> +int main(int argc, char *argv[])
> +{
> +  return 0;
> +} /* { dg-warning "target does not support atomic profile update, single 
> mode is selected" } */

this test FAILs on 32-bit-default x86 configurations like
i386-pc-solaris2.* and i686-pc-linux-gnu for the 64-bit multilib:

FAIL: gcc.dg/profile-update-warning.c  (test for warnings, line 7)
FAIL: gcc.dg/profile-update-warning.c (test for excess errors)

Excess errors:
cc1: error: CPU you selected does not support x86-64 instruction set
cc1: error: CPU you selected does not support x86-64 instruction set

What happens here is that -m64 is added after -march=i386 -m32, causing
the error above.  This doesn't happen for 64-bit-default targets: in the
64-bit case there's just the -m32 from the testcase, for the 32-bit
multilib just another -m32 is added, so the 32-bit case ist tested
twice.

Fixed like this, tested on i386-pc-solaris2.12 and x86_64-pc-linux-gnu,
installed.

Rainer


2016-09-28  Rainer Orth  

* gcc.dg/profile-update-warning.c: Restrict to ia32.
(dg-options): Remove -m32.

# HG changeset patch
# Parent  b421ce4362a3675d9fc4aa98f23e3bfc85b5c4c6
Fix 64-bit gcc.dg/profile-update-warning.c

diff --git a/gcc/testsuite/gcc.dg/profile-update-warning.c b/gcc/testsuite/gcc.dg/profile-update-warning.c
--- a/gcc/testsuite/gcc.dg/profile-update-warning.c
+++ b/gcc/testsuite/gcc.dg/profile-update-warning.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
-/* { dg-options "-fprofile-update=atomic -fprofile-generate -march=i386 -m32" } */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
+/* { dg-options "-fprofile-update=atomic -fprofile-generate -march=i386" } */
 
 int main(int argc, char *argv[])
 {

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-12 Thread Jeff Law

On 09/07/2016 03:34 AM, Martin Liška wrote:

On 09/07/2016 09:45 AM, Christophe Lyon wrote:

> On 6 September 2016 at 15:45, Martin Liška  wrote:

>> On 09/06/2016 03:31 PM, Jakub Jelinek wrote:

>>> sizeof (gcov_type) talks about the host gcov type, you want instead the
>>> target gcov type.  So
>>> TYPE_SIZE (gcov_type_node) == 32 vs. 64 (or TYPE_SIZE_UNIT (gcov_type_node)
>>> == 4 vs. 8).
>>> As SImode and DImode are in fact 4*BITS_PER_UNIT and 8*BITS_PER_UNIT,
>>> TYPE_SIZE_UNIT comparisons for 4 and 8 are most natural.
>>> And I wouldn't add gcc_unreachable, just warn for weirdo arches always.
>>>
>>>   Jakub

>>
>> Thank you Jakub for helping me with that. I've used TYPE_SIZE_UNIT macro.
>>
>> Ready for trunk?
>> Martin

>
> Hi Martin,
>
> On targets which do not support atomic profile update, your patch generates a
> warning on gcc.dg/tree-prof/val-profiler-threads-1.c, making it fail.
>
> Do we need a new effective-target ?
>
> Christophe
>

Hi.

Thanks for observation, I'm sending a patch that does that.
Can you please test it?

Thanks,
Martin


0001-Add-new-effective-target-profile_update_atomic.patch


From 9a68f2fbf2b5cb547aee7860926c846d5f15d398 Mon Sep 17 00:00:00 2001
From: marxin 
Date: Wed, 7 Sep 2016 11:28:13 +0200
Subject: [PATCH] Add new effective target: profile_update_atomic

gcc/testsuite/ChangeLog:

2016-09-07  Martin Liska  

* g++.dg/gcov/gcov-threads-1.C: Use profile_update_atomic
effective target.
* gcc.dg/tree-prof/val-profiler-threads-1.c: Likewise.
* lib/target-supports.exp: Define the new target.

OK.
jeff



Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-07 Thread Christophe Lyon
On 7 September 2016 at 11:34, Martin Liška  wrote:
> On 09/07/2016 09:45 AM, Christophe Lyon wrote:
>> On 6 September 2016 at 15:45, Martin Liška  wrote:
>>> On 09/06/2016 03:31 PM, Jakub Jelinek wrote:
 sizeof (gcov_type) talks about the host gcov type, you want instead the
 target gcov type.  So
 TYPE_SIZE (gcov_type_node) == 32 vs. 64 (or TYPE_SIZE_UNIT (gcov_type_node)
 == 4 vs. 8).
 As SImode and DImode are in fact 4*BITS_PER_UNIT and 8*BITS_PER_UNIT,
 TYPE_SIZE_UNIT comparisons for 4 and 8 are most natural.
 And I wouldn't add gcc_unreachable, just warn for weirdo arches always.

   Jakub
>>>
>>> Thank you Jakub for helping me with that. I've used TYPE_SIZE_UNIT macro.
>>>
>>> Ready for trunk?
>>> Martin
>>
>> Hi Martin,
>>
>> On targets which do not support atomic profile update, your patch generates a
>> warning on gcc.dg/tree-prof/val-profiler-threads-1.c, making it fail.
>>
>> Do we need a new effective-target ?
>>
>> Christophe
>>
>
> Hi.
>
> Thanks for observation, I'm sending a patch that does that.
> Can you please test it?
>
It does work indeed, thanks.
(tested on arm* targets)

Christophe

> Thanks,
> Martin


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-07 Thread Martin Liška
On 09/07/2016 09:45 AM, Christophe Lyon wrote:
> On 6 September 2016 at 15:45, Martin Liška  wrote:
>> On 09/06/2016 03:31 PM, Jakub Jelinek wrote:
>>> sizeof (gcov_type) talks about the host gcov type, you want instead the
>>> target gcov type.  So
>>> TYPE_SIZE (gcov_type_node) == 32 vs. 64 (or TYPE_SIZE_UNIT (gcov_type_node)
>>> == 4 vs. 8).
>>> As SImode and DImode are in fact 4*BITS_PER_UNIT and 8*BITS_PER_UNIT,
>>> TYPE_SIZE_UNIT comparisons for 4 and 8 are most natural.
>>> And I wouldn't add gcc_unreachable, just warn for weirdo arches always.
>>>
>>>   Jakub
>>
>> Thank you Jakub for helping me with that. I've used TYPE_SIZE_UNIT macro.
>>
>> Ready for trunk?
>> Martin
> 
> Hi Martin,
> 
> On targets which do not support atomic profile update, your patch generates a
> warning on gcc.dg/tree-prof/val-profiler-threads-1.c, making it fail.
> 
> Do we need a new effective-target ?
> 
> Christophe
> 

Hi.

Thanks for observation, I'm sending a patch that does that.
Can you please test it?

Thanks,
Martin
>From 9a68f2fbf2b5cb547aee7860926c846d5f15d398 Mon Sep 17 00:00:00 2001
From: marxin 
Date: Wed, 7 Sep 2016 11:28:13 +0200
Subject: [PATCH] Add new effective target: profile_update_atomic

gcc/testsuite/ChangeLog:

2016-09-07  Martin Liska  

	* g++.dg/gcov/gcov-threads-1.C: Use profile_update_atomic
	effective target.
	* gcc.dg/tree-prof/val-profiler-threads-1.c: Likewise.
	* lib/target-supports.exp: Define the new target.
---
 gcc/testsuite/g++.dg/gcov/gcov-threads-1.C  | 1 +
 gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c | 2 ++
 gcc/testsuite/lib/target-supports.exp   | 7 +++
 3 files changed, 10 insertions(+)

diff --git a/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C b/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C
index a4a6f0a..cc9266a 100644
--- a/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C
+++ b/gcc/testsuite/g++.dg/gcov/gcov-threads-1.C
@@ -1,5 +1,6 @@
 /* { dg-options "-fprofile-arcs -ftest-coverage -pthread -fprofile-update=atomic" } */
 /* { dg-do run { target native } } */
+/* { dg-require-effective-target profile_update_atomic } */
 
 #include 
 #include 
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c b/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c
index e9b04a0..95d6ee3 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-profiler-threads-1.c
@@ -1,4 +1,6 @@
 /* { dg-options "-O0 -pthread -fprofile-update=atomic" } */
+/* { dg-require-effective-target profile_update_atomic } */
+
 #include 
 
 #define NUM_THREADS	8
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 545b3dc..6724a7f 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7699,3 +7699,10 @@ proc check_effective_target_offload_hsa { } {
 	int main () {return 0;}
 } "-foffload=hsa" ]
 }
+
+# Return 1 if the target support -fprofile-update=atomic
+proc check_effective_target_profile_update_atomic {} {
+return [check_no_compiler_messages profile_update_atomic assembly {
+	int main (void) { return 0; }
+} "-fprofile-update=atomic -fprofile-generate"]
+}
-- 
2.9.2



Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-07 Thread Christophe Lyon
On 6 September 2016 at 15:45, Martin Liška  wrote:
> On 09/06/2016 03:31 PM, Jakub Jelinek wrote:
>> sizeof (gcov_type) talks about the host gcov type, you want instead the
>> target gcov type.  So
>> TYPE_SIZE (gcov_type_node) == 32 vs. 64 (or TYPE_SIZE_UNIT (gcov_type_node)
>> == 4 vs. 8).
>> As SImode and DImode are in fact 4*BITS_PER_UNIT and 8*BITS_PER_UNIT,
>> TYPE_SIZE_UNIT comparisons for 4 and 8 are most natural.
>> And I wouldn't add gcc_unreachable, just warn for weirdo arches always.
>>
>>   Jakub
>
> Thank you Jakub for helping me with that. I've used TYPE_SIZE_UNIT macro.
>
> Ready for trunk?
> Martin

Hi Martin,

On targets which do not support atomic profile update, your patch generates a
warning on gcc.dg/tree-prof/val-profiler-threads-1.c, making it fail.

Do we need a new effective-target ?

Christophe


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Jakub Jelinek
On Tue, Sep 06, 2016 at 03:45:09PM +0200, Martin Liška wrote:
> --- a/libgcc/libgcov-profiler.c
> +++ b/libgcc/libgcov-profiler.c
> @@ -24,8 +24,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
> If not, see
>  .  */
>  
>  #include "libgcov.h"
> +#include "auto-target.h"
>  #if !defined(inhibit_libc)
>  
> +/* Detect whether target can support atomic update of profilers.  */
> +#if LONG_LONG_TYPE_SIZE <= 32 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
> +#define GCOV_SUPPORTS_ATOMIC 1
> +#else
> +#if LONG_LONG_TYPE_SIZE > 32 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
> +#define GCOV_SUPPORTS_ATOMIC 1
> +#else
> +#define GCOV_SUPPORTS_ATOMIC 0
> +#endif
> +#endif

One more thing.  This is always compiled by gcc, so I think you don't want
to include auto-target.h and use __SIZEOF_LONG_LONG__ == 4 and
__SIZEOF_LONG_LONG__ == 8 tests instead of LONG_LONG_TYPE_SIZE <= 32
or LONG_LONG_TYPE_SIZE > 32.  Ok with that change.

Jakub


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Martin Liška
On 09/06/2016 03:31 PM, Jakub Jelinek wrote:
> sizeof (gcov_type) talks about the host gcov type, you want instead the
> target gcov type.  So
> TYPE_SIZE (gcov_type_node) == 32 vs. 64 (or TYPE_SIZE_UNIT (gcov_type_node)
> == 4 vs. 8).
> As SImode and DImode are in fact 4*BITS_PER_UNIT and 8*BITS_PER_UNIT,
> TYPE_SIZE_UNIT comparisons for 4 and 8 are most natural.
> And I wouldn't add gcc_unreachable, just warn for weirdo arches always.
> 
>   Jakub

Thank you Jakub for helping me with that. I've used TYPE_SIZE_UNIT macro.

Ready for trunk?
Martin
>From 744d1688fee0359314d87d948323f58fbca6172e Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Tue, 6 Sep 2016 14:35:52 +0200
Subject: [PATCH] [PATCH] Detect whether target can use -fprofile-update=atomic

libgcc/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* libgcov-profiler.c: Use __GCC_HAVE_SYNC_COMPARE_AND_SWAP_{4,8} to
	conditionaly enable/disable *_atomic functions.

gcc/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* tree-profile.c (tree_profiling): Detect whether target can use
	-fprofile-update=atomic.

gcc/testsuite/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* gcc.dg/profile-update-warning.c: New test.
---
 gcc/testsuite/gcc.dg/profile-update-warning.c |  7 ++
 gcc/tree-profile.c| 35 +++
 libgcc/libgcov-profiler.c | 24 ++
 3 files changed, 61 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/profile-update-warning.c

diff --git a/gcc/testsuite/gcc.dg/profile-update-warning.c b/gcc/testsuite/gcc.dg/profile-update-warning.c
new file mode 100644
index 000..0614fad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-update-warning.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fprofile-update=atomic -fprofile-generate -march=i386 -m32" } */
+
+int main(int argc, char *argv[])
+{
+  return 0;
+} /* { dg-warning "target does not support atomic profile update, single mode is selected" } */
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 622869e..69b48e5 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -528,6 +528,20 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
   gsi_insert_before (, call, GSI_NEW_STMT);
 }
 
+#ifndef HAVE_sync_compare_and_swapsi
+#define HAVE_sync_compare_and_swapsi 0
+#endif
+#ifndef HAVE_atomic_compare_and_swapsi
+#define HAVE_atomic_compare_and_swapsi 0
+#endif
+
+#ifndef HAVE_sync_compare_and_swapdi
+#define HAVE_sync_compare_and_swapdi 0
+#endif
+#ifndef HAVE_atomic_compare_and_swapdi
+#define HAVE_atomic_compare_and_swapdi 0
+#endif
+
 /* Profile all functions in the callgraph.  */
 
 static unsigned int
@@ -535,6 +549,27 @@ tree_profiling (void)
 {
   struct cgraph_node *node;
 
+  /* Verify whether we can utilize atomic update operations.  */
+  if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
+{
+  bool can_support = false;
+  unsigned HOST_WIDE_INT gcov_type_size
+	= tree_to_uhwi (TYPE_SIZE_UNIT (get_gcov_type ()));
+  if (gcov_type_size == 4)
+	can_support
+	  = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
+  else if (gcov_type_size == 8)
+	can_support
+	  = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
+
+  if (!can_support)
+  {
+	warning (0, "target does not support atomic profile update, "
+		 "single mode is selected");
+	flag_profile_update = PROFILE_UPDATE_SINGLE;
+  }
+}
+
   /* This is a small-ipa pass that gets called only once, from
  cgraphunit.c:ipa_passes().  */
   gcc_assert (symtab->state == IPA_SSA);
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index 70a821d..887041f 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -24,8 +24,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
 #include "libgcov.h"
+#include "auto-target.h"
 #if !defined(inhibit_libc)
 
+/* Detect whether target can support atomic update of profilers.  */
+#if LONG_LONG_TYPE_SIZE <= 32 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#define GCOV_SUPPORTS_ATOMIC 1
+#else
+#if LONG_LONG_TYPE_SIZE > 32 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+#define GCOV_SUPPORTS_ATOMIC 1
+#else
+#define GCOV_SUPPORTS_ATOMIC 0
+#endif
+#endif
+
 #ifdef L_gcov_interval_profiler
 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS.  If the VALUE is above or below
@@ -46,7 +58,7 @@ __gcov_interval_profiler (gcov_type *counters, gcov_type value,
 }
 #endif
 
-#ifdef L_gcov_interval_profiler_atomic
+#if defined(L_gcov_interval_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
 /* If VALUE is in interval <START, STA

Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Jakub Jelinek
On Tue, Sep 06, 2016 at 03:13:09PM +0200, Martin Liška wrote:
> @@ -535,6 +549,27 @@ tree_profiling (void)
>  {
>struct cgraph_node *node;
>  
> +  /* Verify whether we can utilize atomic update operations.  */
> +  if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
> +{
> +  bool can_support = false;
> +  if (sizeof (gcov_type) == 4)
> + can_support
> +   = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
> +  else if (sizeof (gcov_type) == 8)
> + can_support
> +   = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
> +  else
> + gcc_unreachable ();

sizeof (gcov_type) talks about the host gcov type, you want instead the
target gcov type.  So
TYPE_SIZE (gcov_type_node) == 32 vs. 64 (or TYPE_SIZE_UNIT (gcov_type_node)
== 4 vs. 8).
As SImode and DImode are in fact 4*BITS_PER_UNIT and 8*BITS_PER_UNIT,
TYPE_SIZE_UNIT comparisons for 4 and 8 are most natural.
And I wouldn't add gcc_unreachable, just warn for weirdo arches always.

Jakub


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Martin Liška
On 09/06/2016 02:51 PM, Jakub Jelinek wrote:
> On Tue, Sep 06, 2016 at 02:45:32PM +0200, Martin Liška wrote:
>> --- a/gcc/tree-profile.c
>> +++ b/gcc/tree-profile.c
>> @@ -528,6 +528,13 @@ gimple_gen_ior_profiler (histogram_value value, 
>> unsigned tag, unsigned base)
>>gsi_insert_before (, call, GSI_NEW_STMT);
>>  }
>>  
>> +#ifndef HAVE_sync_compare_and_swapsi
>> +#define HAVE_sync_compare_and_swapsi 0
>> +#endif
>> +#ifndef HAVE_atomic_compare_and_swapsi
>> +#define HAVE_atomic_compare_and_swapsi 0
>> +#endif
>> +
>>  /* Profile all functions in the callgraph.  */
>>  
>>  static unsigned int
>> @@ -535,6 +542,16 @@ tree_profiling (void)
>>  {
>>struct cgraph_node *node;
>>  
>> +  /* Verify whether we can utilize atomic update operations.  */
>> +  if (flag_profile_update == PROFILE_UPDATE_ATOMIC
>> +  && !HAVE_sync_compare_and_swapsi
>> +  && !HAVE_atomic_compare_and_swapsi)
> 
> This isn't in sync with:
> 
>> +/* Detect whether target can support atomic update of profilers.  */
>> +#if LONG_LONG_TYPE_SIZE <= 32 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
>> +#define GCOV_SUPPORTS_ATOMIC 1
>> +#else
>> +#if LONG_LONG_TYPE_SIZE > 32 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
>> +#define GCOV_SUPPORTS_ATOMIC 1
>> +#else
>> +#define GCOV_SUPPORTS_ATOMIC 0
>> +#endif
>> +#endif
> 
> this.  Either you implement the poor man's 64-bit atomics with 32-bit cas
> and adjust the latter, or the former needs to look at the target's gcov type
> (long long always?) and depending on its size either test the HAVE_*si or
> HAVE_*di macros.
> 
>   Jakub
> 

Ok, thanks, this should be the proper patch, where I distinguish 
sizeof(gcov_type) and
use appropriate GAVE_*{s,d}i macros.

Ready for trunk?
Thanks,
Martin
>From 41bef1e975042071c973c3cb733a0e0d9a59fec6 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Tue, 6 Sep 2016 14:35:52 +0200
Subject: [PATCH] [PATCH] Detect whether target can use -fprofile-update=atomic

libgcc/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* libgcov-profiler.c: Use __GCC_HAVE_SYNC_COMPARE_AND_SWAP_{4,8} to
	conditionaly enable/disable *_atomic functions.

gcc/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* tree-profile.c (tree_profiling): Detect whether target can use
	-fprofile-update=atomic.

gcc/testsuite/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* gcc.dg/profile-update-warning.c: New test.
---
 gcc/testsuite/gcc.dg/profile-update-warning.c |  7 ++
 gcc/tree-profile.c| 35 +++
 libgcc/libgcov-profiler.c | 24 ++
 3 files changed, 61 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/profile-update-warning.c

diff --git a/gcc/testsuite/gcc.dg/profile-update-warning.c b/gcc/testsuite/gcc.dg/profile-update-warning.c
new file mode 100644
index 000..0614fad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-update-warning.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fprofile-update=atomic -fprofile-generate -march=i386 -m32" } */
+
+int main(int argc, char *argv[])
+{
+  return 0;
+} /* { dg-warning "target does not support atomic profile update, single mode is selected" } */
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 622869e..a3e6dca 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -528,6 +528,20 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
   gsi_insert_before (, call, GSI_NEW_STMT);
 }
 
+#ifndef HAVE_sync_compare_and_swapsi
+#define HAVE_sync_compare_and_swapsi 0
+#endif
+#ifndef HAVE_atomic_compare_and_swapsi
+#define HAVE_atomic_compare_and_swapsi 0
+#endif
+
+#ifndef HAVE_sync_compare_and_swapdi
+#define HAVE_sync_compare_and_swapdi 0
+#endif
+#ifndef HAVE_atomic_compare_and_swapdi
+#define HAVE_atomic_compare_and_swapdi 0
+#endif
+
 /* Profile all functions in the callgraph.  */
 
 static unsigned int
@@ -535,6 +549,27 @@ tree_profiling (void)
 {
   struct cgraph_node *node;
 
+  /* Verify whether we can utilize atomic update operations.  */
+  if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
+{
+  bool can_support = false;
+  if (sizeof (gcov_type) == 4)
+	can_support
+	  = HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi;
+  else if (sizeof (gcov_type) == 8)
+	can_support
+	  = HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi;
+  else
+	gcc_unreachable ();
+
+  if (!can_support)
+  {
+	warning (0, "target does not support atomic profile update, "
+		 "single mode is selected");
+	flag_profile_update = PR

Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Jakub Jelinek
On Tue, Sep 06, 2016 at 02:45:32PM +0200, Martin Liška wrote:
> --- a/gcc/tree-profile.c
> +++ b/gcc/tree-profile.c
> @@ -528,6 +528,13 @@ gimple_gen_ior_profiler (histogram_value value, unsigned 
> tag, unsigned base)
>gsi_insert_before (, call, GSI_NEW_STMT);
>  }
>  
> +#ifndef HAVE_sync_compare_and_swapsi
> +#define HAVE_sync_compare_and_swapsi 0
> +#endif
> +#ifndef HAVE_atomic_compare_and_swapsi
> +#define HAVE_atomic_compare_and_swapsi 0
> +#endif
> +
>  /* Profile all functions in the callgraph.  */
>  
>  static unsigned int
> @@ -535,6 +542,16 @@ tree_profiling (void)
>  {
>struct cgraph_node *node;
>  
> +  /* Verify whether we can utilize atomic update operations.  */
> +  if (flag_profile_update == PROFILE_UPDATE_ATOMIC
> +  && !HAVE_sync_compare_and_swapsi
> +  && !HAVE_atomic_compare_and_swapsi)

This isn't in sync with:

> +/* Detect whether target can support atomic update of profilers.  */
> +#if LONG_LONG_TYPE_SIZE <= 32 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
> +#define GCOV_SUPPORTS_ATOMIC 1
> +#else
> +#if LONG_LONG_TYPE_SIZE > 32 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
> +#define GCOV_SUPPORTS_ATOMIC 1
> +#else
> +#define GCOV_SUPPORTS_ATOMIC 0
> +#endif
> +#endif

this.  Either you implement the poor man's 64-bit atomics with 32-bit cas
and adjust the latter, or the former needs to look at the target's gcov type
(long long always?) and depending on its size either test the HAVE_*si or
HAVE_*di macros.

Jakub


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Martin Liška
On 09/06/2016 02:38 PM, David Edelsohn wrote:
> On Tue, Sep 6, 2016 at 8:14 AM, Nathan Sidwell <nat...@acm.org> wrote:
>> On 09/06/16 06:57, David Edelsohn wrote:
>>
>>> What about Jakub's comment in the PR?
>>>
>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77378#c6
>>
>>
>> This needs addressing.  Can you clarify PPC behaviour, because I may have
>> misunderstood:
>>
>> 1) PPC currently has 64 bit counters -- but cannot support 64bit atomic ops
>> in 32 bit mode.
>>
>> 2) PPC currently has 32 bit counters anyway.
> 
> The rs6000 port ABIs implement 64 bit "long long" type.  The current
> code uses LONG_LONG_TYPE_SIZE for the counters.  I assume that most
> ports don't support native 64 bit atomic operations in 32 bit ABI --
> PowerPC does not.
> 
> The previous code allowed gcov type to be overridden, but I don't
> think that it was 32 bit on most targets.
> 
>>
>> I had interpreted the comment to be implying #2, but now I'm not so sure.
>>
>>> The proposed patch seems wrong or at least incomplete.  The recent
>>> change is imposing a 64 bit DImode counter when producing 32 bit code.
>>> PowerPC does support 64 bit atomic operations in 32 bit mode.
>>
>>
>> I'm presuming you've missed a 'NOT' in that sentence.
> 
> Yes, I omitted a "NOT".
> 
> PowerPC64 has 64 bit atomics, but PowerPC32 subset only provides 32
> bit atomics in the ISA.
> 
> If the counters always should be 64 bit, then a poor-man's 64 bit
> atomic operation proposed by Jakub seems like a better solution.
> 
> Thanks, David

Hi David.

I sent the previous email before I read the Jakub's comment.
I'm attaching simplified patch (based of the comment), which works for i386
target. I'm testing that on on m68k target.

I prefer to have a single type for one config, same what Nathan suggested.
I like the idea of poor-man's atomics, I can make an incremental patch.

Martin

> 
>>
>>> Was there a design decision that profile counters always should be 64
>>> bits?  Either 32 bit targets won't support multi-threaded profiling or
>>> 32 bit targets can overflow the counter sooner.
>>
>>
>>
>>>  Which is worse?
>>> Which is more likely?
>>
>>
>> My initial thought is that it is probably awkward to support 2 different
>> sized counter types in the 'same' config.  I.e. 64-bit single-threaded
>> counters and 32-bit threaded counters.
>>
>> nathan

>From 44289abf2e3ecfb7e17c6f204b280af06bf20b0e Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Tue, 6 Sep 2016 14:35:52 +0200
Subject: [PATCH] [PATCH] Detect whether target can use -fprofile-update=atomic

libgcc/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* libgcov-profiler.c: Use __GCC_HAVE_SYNC_COMPARE_AND_SWAP_{4,8} to
	conditionaly enable/disable *_atomic functions.

gcc/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* tree-profile.c (tree_profiling): Detect whether target can use
	-fprofile-update=atomic.

gcc/testsuite/ChangeLog:

2016-09-06  Martin Liska  <mli...@suse.cz>

	* gcc.dg/profile-update-warning.c: New test.
---
 gcc/testsuite/gcc.dg/profile-update-warning.c |  7 +++
 gcc/tree-profile.c| 17 +
 libgcc/libgcov-profiler.c | 24 +++-
 3 files changed, 43 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/profile-update-warning.c

diff --git a/gcc/testsuite/gcc.dg/profile-update-warning.c b/gcc/testsuite/gcc.dg/profile-update-warning.c
new file mode 100644
index 000..0614fad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-update-warning.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fprofile-update=atomic -fprofile-generate -march=i386 -m32" } */
+
+int main(int argc, char *argv[])
+{
+  return 0;
+} /* { dg-warning "target does not support atomic profile update, single mode is selected" } */
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 622869e..8ce35be 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -528,6 +528,13 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
   gsi_insert_before (, call, GSI_NEW_STMT);
 }
 
+#ifndef HAVE_sync_compare_and_swapsi
+#define HAVE_sync_compare_and_swapsi 0
+#endif
+#ifndef HAVE_atomic_compare_and_swapsi
+#define HAVE_atomic_compare_and_swapsi 0
+#endif
+
 /* Profile all functions in the callgraph.  */
 
 static unsigned int
@@ -535,6 +542,16 @@ tree_profiling (void)
 {
   struct cgraph_node *node;
 
+  /* Verify whether we can utilize atomic update operations.  */
+  if (flag_profile_update == PROFILE_UPDATE_ATOMIC
+

Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread David Edelsohn
On Tue, Sep 6, 2016 at 8:26 AM, Jakub Jelinek  wrote:
> On Tue, Sep 06, 2016 at 08:14:58AM -0400, Nathan Sidwell wrote:
>> On 09/06/16 06:57, David Edelsohn wrote:
>>
>> >What about Jakub's comment in the PR?
>> >
>> >https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77378#c6
>>
>> This needs addressing.  Can you clarify PPC behaviour, because I may have
>> misunderstood:
>>
>> 1) PPC currently has 64 bit counters -- but cannot support 64bit atomic ops
>> in 32 bit mode.
>>
>> 2) PPC currently has 32 bit counters anyway.
>>
>> I had interpreted the comment to be implying #2, but now I'm not so sure.
>
> Aren't the counters 64-bit everywhere?
> Even with 32-bit atomics, as the only operation needed is addition, can't it
> be implemented anyway?  Instead of:
>   __atomic_fetch_add_8 (, 1, __ATOMIC_RELAXED);
> one could for e.g. little endian:
>   if (__atomic_add_fetch_4 ((unsigned int *) , 1, __ATOMIC_RELAXED) == 0)
> __atomic_fetch_add_4 (((unsigned int *) ) + 1, 1, __ATOMIC_RELAXED);

Is this correct for either endianness?

- David

> There is a small risk that e.g. SIGTERM happens in between the two and the
> counters are written into the file without the upper half being bumped, but
> compared to the non-atomic updates it is much less likely (and, if you
> actually never overflow the counters, it won't be an issue anyway).
>
> Jakub


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Jakub Jelinek
On Tue, Sep 06, 2016 at 08:14:58AM -0400, Nathan Sidwell wrote:
> On 09/06/16 06:57, David Edelsohn wrote:
> 
> >What about Jakub's comment in the PR?
> >
> >https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77378#c6
> 
> This needs addressing.  Can you clarify PPC behaviour, because I may have
> misunderstood:
> 
> 1) PPC currently has 64 bit counters -- but cannot support 64bit atomic ops
> in 32 bit mode.
> 
> 2) PPC currently has 32 bit counters anyway.
> 
> I had interpreted the comment to be implying #2, but now I'm not so sure.

Aren't the counters 64-bit everywhere?
Even with 32-bit atomics, as the only operation needed is addition, can't it
be implemented anyway?  Instead of:
  __atomic_fetch_add_8 (, 1, __ATOMIC_RELAXED);
one could for e.g. little endian:
  if (__atomic_add_fetch_4 ((unsigned int *) , 1, __ATOMIC_RELAXED) == 0)
__atomic_fetch_add_4 (((unsigned int *) ) + 1, 1, __ATOMIC_RELAXED);
There is a small risk that e.g. SIGTERM happens in between the two and the
counters are written into the file without the upper half being bumped, but
compared to the non-atomic updates it is much less likely (and, if you
actually never overflow the counters, it won't be an issue anyway).

Jakub


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Nathan Sidwell

On 09/06/16 06:57, David Edelsohn wrote:


What about Jakub's comment in the PR?

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77378#c6


This needs addressing.  Can you clarify PPC behaviour, because I may have 
misunderstood:


1) PPC currently has 64 bit counters -- but cannot support 64bit atomic ops in 
32 bit mode.


2) PPC currently has 32 bit counters anyway.

I had interpreted the comment to be implying #2, but now I'm not so sure.


The proposed patch seems wrong or at least incomplete.  The recent
change is imposing a 64 bit DImode counter when producing 32 bit code.
PowerPC does support 64 bit atomic operations in 32 bit mode.


I'm presuming you've missed a 'NOT' in that sentence.


Was there a design decision that profile counters always should be 64
bits?  Either 32 bit targets won't support multi-threaded profiling or
32 bit targets can overflow the counter sooner.




 Which is worse?
Which is more likely?


My initial thought is that it is probably awkward to support 2 different sized 
counter types in the 'same' config.  I.e. 64-bit single-threaded counters and 
32-bit threaded counters.


nathan


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread David Edelsohn
On Tue, Sep 6, 2016 at 6:45 AM, Martin Liška  wrote:

>>> Proper fix contains of 2 parts:
>>> a) compiler emission must verify that -fprofile-update=atomic is doable for 
>>> a given target; it's done
>>> via a new function can_generate_atomic_builtin
>>> b) libgcc must detect whether __atomic_fetch_add_x can be expanded on the 
>>> target; that requires configure
>>> support and if the target is not capable to expand these, we must 
>>> conditionally remove all gcov_.*profiler_atomic
>>> functions from libgcov.a.
>>
>> I'm fine with the coverage-pecific changes, but the new hooks etc are not 
>> something I can approve.
>>
>> gcc/ChangeLog:
>>
>> 2016-08-12  Martin Liska  
>>
>> * optabs.c (can_generate_atomic_builtin): New function.
>> * optabs.h (can_generate_atomic_builtin): Declare the function.
>> Need GWM or similar review
>>
>> * tree-profile.c (tree_profiling):  Detect whether target can use
>> -fprofile-update=atomic.
>> ok
>>
>> gcc/testsuite/ChangeLog:
>>
>> 2016-08-12  Martin Liska  
>>
>> * gcc.dg/profile-update-warning.c: New test.
>> ok
>>
>> libgcc/ChangeLog:
>>
>> 2016-08-16  Martin Liska  
>>
>> * acinclude.m4: New file.
>> * config.in: New macro defines.
>> * configure: Regenerated.
>> * configure.ac: Detect atomic operations.
>> need GWM or similar review
>>
>> * libgcov-profiler.c: Detect GCOV_SUPPORTS_ATOMIC and
>> conditionaly enable/disable *_atomic functions.
>> OK.
>>
>> nathan
>
> Hi Nathan.
>
> Thanks for review, I'm CCing Jakub and Richard for the review.
> The patch should fix very similar issue spotted on AIX target by David.

What about Jakub's comment in the PR?

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77378#c6

The proposed patch seems wrong or at least incomplete.  The recent
change is imposing a 64 bit DImode counter when producing 32 bit code.
PowerPC does support 64 bit atomic operations in 32 bit mode.

Was there a design decision that profile counters always should be 64
bits?  Either 32 bit targets won't support multi-threaded profiling or
32 bit targets can overflow the counter sooner.  Which is worse?
Which is more likely?

Thanks, David


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-09-06 Thread Martin Liška
On 08/16/2016 04:30 PM, Nathan Sidwell wrote:
> On 08/16/16 08:55, Martin Liška wrote:
>> Hello.
>>
>> As reported in [1], m68k has been broken since I installed the patch. Reason 
>> is that the target
>> does not support atomic operations (add, or) for a mode of gcov_type. 
>> Because of that, we see
>> an undefined symbols.
>>
>> Proper fix contains of 2 parts:
>> a) compiler emission must verify that -fprofile-update=atomic is doable for 
>> a given target; it's done
>> via a new function can_generate_atomic_builtin
>> b) libgcc must detect whether __atomic_fetch_add_x can be expanded on the 
>> target; that requires configure
>> support and if the target is not capable to expand these, we must 
>> conditionally remove all gcov_.*profiler_atomic
>> functions from libgcov.a.
> 
> I'm fine with the coverage-pecific changes, but the new hooks etc are not 
> something I can approve.
> 
> gcc/ChangeLog:
> 
> 2016-08-12  Martin Liska  
> 
> * optabs.c (can_generate_atomic_builtin): New function.
> * optabs.h (can_generate_atomic_builtin): Declare the function.
> Need GWM or similar review
> 
> * tree-profile.c (tree_profiling):  Detect whether target can use
> -fprofile-update=atomic.
> ok
> 
> gcc/testsuite/ChangeLog:
> 
> 2016-08-12  Martin Liska  
> 
> * gcc.dg/profile-update-warning.c: New test.
> ok
> 
> libgcc/ChangeLog:
> 
> 2016-08-16  Martin Liska  
> 
> * acinclude.m4: New file.
> * config.in: New macro defines.
> * configure: Regenerated.
> * configure.ac: Detect atomic operations.
> need GWM or similar review
> 
> * libgcov-profiler.c: Detect GCOV_SUPPORTS_ATOMIC and
> conditionaly enable/disable *_atomic functions.
> OK.
> 
> nathan

Hi Nathan.

Thanks for review, I'm CCing Jakub and Richard for the review.
The patch should fix very similar issue spotted on AIX target by David.

Thanks,
Martin


Re: [PATCH] Detect whether target can use -fprofile-update=atomic

2016-08-16 Thread Nathan Sidwell

On 08/16/16 08:55, Martin Liška wrote:

Hello.

As reported in [1], m68k has been broken since I installed the patch. Reason is 
that the target
does not support atomic operations (add, or) for a mode of gcov_type. Because 
of that, we see
an undefined symbols.

Proper fix contains of 2 parts:
a) compiler emission must verify that -fprofile-update=atomic is doable for a 
given target; it's done
via a new function can_generate_atomic_builtin
b) libgcc must detect whether __atomic_fetch_add_x can be expanded on the 
target; that requires configure
support and if the target is not capable to expand these, we must conditionally 
remove all gcov_.*profiler_atomic
functions from libgcov.a.


I'm fine with the coverage-pecific changes, but the new hooks etc are not 
something I can approve.


gcc/ChangeLog:

2016-08-12  Martin Liska  

* optabs.c (can_generate_atomic_builtin): New function.
* optabs.h (can_generate_atomic_builtin): Declare the function.
Need GWM or similar review

* tree-profile.c (tree_profiling):  Detect whether target can use
-fprofile-update=atomic.
ok

gcc/testsuite/ChangeLog:

2016-08-12  Martin Liska  

* gcc.dg/profile-update-warning.c: New test.
ok

libgcc/ChangeLog:

2016-08-16  Martin Liska  

* acinclude.m4: New file.
* config.in: New macro defines.
* configure: Regenerated.
* configure.ac: Detect atomic operations.
need GWM or similar review

* libgcov-profiler.c: Detect GCOV_SUPPORTS_ATOMIC and
conditionaly enable/disable *_atomic functions.
OK.

nathan


[PATCH] Detect whether target can use -fprofile-update=atomic

2016-08-16 Thread Martin Liška
Hello.

As reported in [1], m68k has been broken since I installed the patch. Reason is 
that the target
does not support atomic operations (add, or) for a mode of gcov_type. Because 
of that, we see
an undefined symbols.

Proper fix contains of 2 parts:
a) compiler emission must verify that -fprofile-update=atomic is doable for a 
given target; it's done
via a new function can_generate_atomic_builtin
b) libgcc must detect whether __atomic_fetch_add_x can be expanded on the 
target; that requires configure
support and if the target is not capable to expand these, we must conditionally 
remove all gcov_.*profiler_atomic
functions from libgcov.a.

Andreas reported that it fixes the test-case mentioned in the PR and I tested 
that on -march=i386.
Apart from that I've been doing bootstrap on x86_64-linux-gnu.

Ready after it finishes?
Martin

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58306#c30
>From a5c6dbdbabc36193f7becce78af58b276b0d3660 Mon Sep 17 00:00:00 2001
From: marxin 
Date: Tue, 16 Aug 2016 10:13:13 +0200
Subject: [PATCH 2/2] Detect whether target can use -fprofile-update=atomic

gcc/ChangeLog:

2016-08-12  Martin Liska  

	* optabs.c (can_generate_atomic_builtin): New function.
	* optabs.h (can_generate_atomic_builtin): Declare the function.
	* tree-profile.c (tree_profiling):  Detect whether target can use
	-fprofile-update=atomic.

gcc/testsuite/ChangeLog:

2016-08-12  Martin Liska  

	* gcc.dg/profile-update-warning.c: New test.

libgcc/ChangeLog:

2016-08-16  Martin Liska  

	* acinclude.m4: New file.
	* config.in: New macro defines.
	* configure: Regenerated.
	* configure.ac: Detect atomic operations.
	* libgcov-profiler.c: Detect GCOV_SUPPORTS_ATOMIC and
	conditionaly enable/disable *_atomic functions.
---
 gcc/optabs.c  |  13 ++
 gcc/optabs.h  |   5 +
 gcc/testsuite/gcc.dg/profile-update-warning.c |   7 +
 gcc/tree-profile.c|  18 +++
 libgcc/acinclude.m4   |  22 
 libgcc/config.in  |  15 ++-
 libgcc/configure  | 179 +-
 libgcc/configure.ac   |   8 ++
 libgcc/libgcov-profiler.c |  24 +++-
 9 files changed, 279 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/profile-update-warning.c
 create mode 100644 libgcc/acinclude.m4

diff --git a/gcc/optabs.c b/gcc/optabs.c
index 87b4f97..3be0dfe 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -6476,6 +6476,19 @@ get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
 }
 }
 
+bool
+can_generate_atomic_builtin (enum rtx_code code, machine_mode mode)
+{
+  struct atomic_op_functions optab;
+  get_atomic_op_for_code (, code);
+  enum insn_code icode = direct_optab_handler (optab.mem_no_result, mode);
+  if (icode != CODE_FOR_nothing)
+return true;
+
+  return can_compare_and_swap_p (mode, false)
+|| can_compare_and_swap_p (mode, true);
+}
+
 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
using memory order MODEL.  If AFTER is true the operation needs to return
the value of *MEM after the operation, otherwise the previous value.  
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 03fd94d..769685a 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -348,4 +348,9 @@ extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
 
 extern enum rtx_code get_rtx_code (enum tree_code tcode, bool unsignedp);
 
+/* Return true when a target is capable of expansion of an atomic builtin
+   with CODE of a specified machine MODE.  */
+
+extern bool can_generate_atomic_builtin (enum rtx_code code, machine_mode mode);
+
 #endif /* GCC_OPTABS_H */
diff --git a/gcc/testsuite/gcc.dg/profile-update-warning.c b/gcc/testsuite/gcc.dg/profile-update-warning.c
new file mode 100644
index 000..0614fad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-update-warning.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fprofile-update=atomic -fprofile-generate -march=i386 -m32" } */
+
+int main(int argc, char *argv[])
+{
+  return 0;
+} /* { dg-warning "target does not support atomic profile update, single mode is selected" } */
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 622869e..799de84 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -49,6 +49,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "profile.h"
 #include "tree-cfgcleanup.h"
 #include "params.h"
+#include "rtl.h"
+#include "optabs.h"
 
 static GTY(()) tree gcov_type_node;
 static GTY(()) tree tree_interval_profiler_fn;
@@ -535,6 +537,22 @@ tree_profiling (void)
 {
   struct cgraph_node *node;
 
+  /* Verify whether we can utilize atomic update operations.  */
+  if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
+{
+