Re: [PATCH RFA] tree-inline: Fix VLA handling [PR95552]

2020-06-06 Thread Eric Botcazou
> This patch fixes walk_tree_1 to call the function on the TYPE_DECL, as we do
> for other decls of a DECL_EXPR.

Where is that done exactly?  The only case handled by DECL_EXPR is TYPE_DECL.

The correct thing to do is clearly implied by the first line in your patch.

-- 
Eric Botcazou


[PATCH] x86: Improve expansion of __builtin_parity

2020-06-06 Thread Roger Sayle
 

This patch changes the way that __builtin_parity is expanded in i386.md.

This changes the code generated for the function:

 

int test(unsigned char a)

{

   unsigned char x = a + 1;

   return __builtin_parity(x);

}

 

from this before the patch:

 

test:   addl$1, %edi

movzbl  %dil, %edi

movl%edi, %eax

shrl$16, %edi

xorl%edi, %eax

xorb%ah, %al

setnp   %al

movzbl  %al, %eax

ret

 

to this with the patch:

 

test:   leal1(%rdi), %eax

testb   %al, %al

setnp   %al

movzbl  %al, %eax

ret

 

GCC currently hides the shift and xor reduction inside a backend

specific UNSPEC PARITY, making it invisible to the RTL optimizers until

very late during compilation.  It is normally reasonable for the

middle-end to maintain wider mode representations for as long as possible

and split them later, but this only helps if the semantics are visible

at the RTL-level (to combine and other passes), but UNSPECs are black

boxes, so in this case splitting early (during RTL expansion) is a

better strategy.

 

I'd originally written this patch after investigating whether GCC could

generate the x86's "jp" and "jnp" conditional branch on parity flag,

and noticed the inefficient reduction.  It was only when I was preparing

this patch for submission that I discovered that this is actually a

regression fix, and that Uros had already implemented/thought about the

above optimization back in 2007.  Indeed the example above is taken from

https://gcc.gnu.org/legacy-ml/gcc-patches/2007-02/msg00972.html

 

Alas there is a mismatch between RTL's definition of PARITY operation

which has an integer mode result, and the x86's parity flag.  So when

Uros addressed PR target/44481 in 2010, by introducing UNSPEC PARITY,

we lost some of the optimization opportunities of his original patch.

https://gcc.gnu.org/legacy-ml/gcc-patches/2010-06/msg01259.html

The early splitting approach in this patch safely restores the 2007-2010

optimization opportunities.

 

 

It turns out that that popcount instruction on modern x86_64 processors

has (almost) made the integer parity flag in the x86 ALU completely

obsolete, especially as POPCOUNT's integer semantics are a much better

fit to RTL.  The one remaining case where these transistors are useful

is where __builtin_parity is immediately tested by a conditional branch,

and therefore the result is wanted in a flags register rather than as

an integer.  This case is captured by two peephole2 optimizations in

the attached patch.

 

Hence the code:

 

void foo(unsigned char x)

{

  if (__builtin_parity(x))

bar();

}

 

which on modern hardware is currently generated as:

 

foo:movzbl  %dil, %edi

popcntl %edi, %edi

andl$1, %edi

jne .L4

ret

.L4:jmp bar

 

with this patch will be generated as:

 

foo:testb   %dil, %dil

jnp .L4

ret

.L4:jmp bar

 

 

[I believe that popcount has a 3-cycle latency, but a test followed by a

conditional branch can dispatch in the same cycle, but I'm not an expert].

The new parityhi2 and parityqi2 expanders are infrastructure to support

(possible) future middle-end changes.

 

 

This patch has been tested with a "make bootstrap" and "make -k check" on

x86_64-pc-linux-gnu with no regressions.  I've also added 7 new test cases;

4 tests gcc.target/i386/parity-[3-6].c check the existing behaviour, and

3 tests gcc.target/i386/parity-[7-9].c check the changes from this patch.

 

 

Alas I'm very out of practice contributing patches (but my paperwork should

still be valid), so if a friendly i386/x86_64 backend maintainer could take

care of things from here, that would be very much appreciated.

 

Many thanks in advance,

Roger

--

 

2020-06-05  Roger Sayle  

 

* config/i386/i386.md (paritydi2, paritysi2): Expand reduction

via shift and xor to an USPEC PARITY matching a parityhi2_cmp.

(paritydi2_cmp, paritysi2_cmp): Delete these define_insn_and_split.

(parityhi2, parityqi2): New expanders.

(parityhi2_cmp): Implement set parity flag with xorb insn.

(parityqi2_cmp): Implement set parity flag with testb insn.

New peephole2s to use these insns (UNSPEC PARITY) when appropriate.

 

2020-06-05  Roger Sayle  

 

* gcc.target/i386/parity-[3-9].c: New tests.

 

 

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 459cf62..6659657 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -14780,9 +14780,32 @@
   "! TARGET_POPCNT"
 {
   rtx scratch = gen_reg_rtx (QImode);
+  rtx hipart1 = gen_reg_rtx (SImode);
+  rtx lopart1 = gen_reg_rtx (SImode);
+  rtx xor1 = gen_reg_rtx (SImode);
+  rtx shift2 = gen_reg_rtx (SImode);
+  rtx hipart2 = gen_reg_rtx (HImode);
+  rtx lopart2 = gen_reg_rtx (HImode);
+  rtx xor2 = gen_reg_rtx (HImod

[committed] wwwdocs: Add markup to the GCC 11 -dump* and -aux* revamp.

2020-06-06 Thread Gerald Pfeifer
This is a little follow up to Alexandre's note for the GCC 11 release
notes - we usually mark command-line options as .

Pushed.

Gerald
---
 htdocs/gcc-11/changes.html | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/htdocs/gcc-11/changes.html b/htdocs/gcc-11/changes.html
index 2f00d1f1..9dba1e14 100644
--- a/htdocs/gcc-11/changes.html
+++ b/htdocs/gcc-11/changes.html
@@ -32,8 +32,9 @@ a work-in-progress.
 
   Naming and location of auxiliary and dump output files changed.
   If you compile multiple input files in a single command, if you
-  enable Link Time Optimization, or if you use -dumpbase,
-  -dumpdir, -save-temps=*, and you expect any file other than the
+  enable Link Time Optimization, or if you use -dumpbase,
+  -dumpdir, -save-temps=*, and you expect
+  any file other than the
   primary output file(s) to be created as a side effect, watch out
   for improvements and a few surprises.
   See https://gcc.gnu.org/pipermail/gcc-patches/2020-May/546494.html";>the
-- 
2.26.2


Re: [PATCH] Libsanitizer: merge from master.

2020-06-06 Thread Andreas Schwab
^
  |:
 1898 |   case 0b10'110:  // c.swsp
  |   
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1898:7: error: 
duplicate case value
 1898 |   case 0b10'110:  // c.swsp
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1880:7: note: 
previously used here
 1880 |   case 0b10'010:  // c.lwsp (rd != x0)
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1898:16: error: 
expected ':' before 'case'
 1898 |   case 0b10'110:  // c.swsp
  |^
  |:
 1899 | #if __riscv_flen >= 32 || __riscv_xlen == 64
 1900 |   case 0b00'111:  // c.fsw / c.sd
  |   
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1900:7: error: 
duplicate case value
 1900 |   case 0b00'111:  // c.fsw / c.sd
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1885:7: note: 
previously used here
 1885 |   case 0b00'010:  // c.lw
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1900:16: error: 
expected ':' before 'case'
 1900 |   case 0b00'111:  // c.fsw / c.sd
  |^
  |:
 1901 |   case 0b10'111:  // c.fswsp / c.sdsp
  |   
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1901:7: error: 
duplicate case value
 1901 |   case 0b10'111:  // c.fswsp / c.sdsp
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1880:7: note: 
previously used here
 1880 |   case 0b10'010:  // c.lwsp (rd != x0)
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1901:16: error: 
expected ':' before 'case'
 1901 |   case 0b10'111:  // c.fswsp / c.sdsp
  |^
  |:
 1904 |   case 0b00'101:  // c.fsd
  |   
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1904:7: error: 
duplicate case value
 1904 |   case 0b00'101:  // c.fsd
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1885:7: note: 
previously used here
 1885 |   case 0b00'010:  // c.lw
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1904:16: error: 
expected ':' before 'case'
 1904 |   case 0b00'101:  // c.fsd
  |^
  |:
 1905 |   case 0b10'101:  // c.fsdsp
      |   
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1905:7: error: 
duplicate case value
 1905 |   case 0b10'101:  // c.fsdsp
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1880:7: note: 
previously used here
 1880 |   case 0b10'010:  // c.lwsp (rd != x0)
  |   ^~~~
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cpp:1905:16: error: 
expected ':' before 'return'
 1905 |   case 0b10'101:  // c.fsdsp
  |^
  |:
 1906 | #endif
 1907 | return SignalContext::WRITE;
  | ~~
make[4]: *** [Makefile:614: sanitizer_linux.lo] Error 1
make[4]: Leaving directory 
'/daten/riscv64/gcc/gcc-20200606/Build/riscv64-suse-linux/libsanitizer/sanitizer_common'
make[3]: *** [Makefile:528: all-recursive] Error 1
make[3]: Leaving directory 
'/daten/riscv64/gcc/gcc-20200606/Build/riscv64-suse-linux/libsanitizer'
make[2]: *** [Makefile:415: all] Error 2
make[2]: Leaving directory 
'/daten/riscv64/gcc/gcc-20200606/Build/riscv64-suse-linux/libsanitizer'
make[1]: *** [Makefile:17025: all-target-libsanitizer] Error 2

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


Fix ICE in ODR enum streaming

2020-06-06 Thread Jan Hubicka
Hi,
this fixes ICE when enum value does not fit HOST_WIDE_INT.

Bootstrapped/retested x86_64-linux, comitted.

gcc/ChangeLog:

2020-06-06  Jan Hubicka  

PR lto/95548
* ipa-devirt.c (struct odr_enum_val): Turn values to wide_int.
(ipa_odr_summary_write): Update streaming.
(ipa_odr_read_section): Update streaming.

gcc/testsuite/ChangeLog:

2020-06-06  Jan Hubicka  

* g++.dg/torture/pr95548.C: New test.

diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 8e36ff1ea1d..0340decba9b 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -505,7 +505,7 @@ static GTY(()) vec  *odr_enums;
 struct odr_enum_val
 {
   const char *name;
-  HOST_WIDE_INT val;
+  wide_int val;
   location_t locus;
 };
 
@@ -4048,8 +4048,9 @@ ipa_odr_summary_write (void)
  streamer_write_string (ob, ob->main_stream,
 IDENTIFIER_POINTER (TREE_PURPOSE (e)),
 true);
- streamer_write_hwi (ob, tree_to_shwi
-   (DECL_INITIAL (TREE_VALUE (e;
+ streamer_write_wide_int (ob,
+  wi::to_wide (DECL_INITIAL
+ (TREE_VALUE (e;
}
 
  bitpack_d bp = bitpack_create (ob->main_stream);
@@ -4080,7 +4081,7 @@ ipa_odr_summary_write (void)
{
  streamer_write_string (ob, ob->main_stream,
 this_enum.vals[j].name, true);
- streamer_write_hwi (ob, this_enum.vals[j].val);
+ streamer_write_wide_int (ob, this_enum.vals[j].val);
}
 
  bitpack_d bp = bitpack_create (ob->main_stream);
@@ -4139,35 +4140,51 @@ ipa_odr_read_section (struct lto_file_decl_data 
*file_data, const char *data,
   class odr_enum &this_enum
 = odr_enum_map->get_or_insert (xstrdup (name), &existed_p);
 
+  /* If this is first time we see the enum, remember its definition.  */
   if (!existed_p)
{
  this_enum.vals.safe_grow_cleared (nvals);
  this_enum.warned = false;
+ if (dump_file)
+   fprintf (dump_file, "enum %s\n{\n", name);
  for (unsigned j = 0; j < nvals; j++)
{
  const char *val_name = streamer_read_string (data_in, &ib);
  obstack_grow (&odr_enum_obstack, val_name, strlen (val_name) + 1);
  this_enum.vals[j].name = XOBFINISH (&odr_enum_obstack, char *);
- this_enum.vals[j].val = streamer_read_hwi (&ib);
+ this_enum.vals[j].val = streamer_read_wide_int (&ib);
+ if (dump_file)
+   fprintf (dump_file, "  %s = " HOST_WIDE_INT_PRINT_DEC ",\n",
+val_name, wi::fits_shwi_p (this_enum.vals[j].val)
+? this_enum.vals[j].val.to_shwi () : -1);
}
  bitpack_d bp = streamer_read_bitpack (&ib);
  stream_input_location (&this_enum.locus, &bp, data_in);
  for (unsigned j = 0; j < nvals; j++)
stream_input_location (&this_enum.vals[j].locus, &bp, data_in);
  data_in->location_cache.apply_location_cache ();
+ if (dump_file)
+   fprintf (dump_file, "}\n");
}
+  /* If we already have definition, compare it with new one and output
+warnings if they differs.  */
   else
{
  int do_warning = -1;
  char *warn_name = NULL;
- HOST_WIDE_INT warn_value = 0;
+ wide_int warn_value = wi::zero (1);
 
+ if (dump_file)
+   fprintf (dump_file, "Comparing enum %s\n", name);
+
+ /* Look for differences which we will warn about later once locations
+are streamed.  */
  for (unsigned j = 0; j < nvals; j++)
{
  const char *id = streamer_read_string (data_in, &ib);
- HOST_WIDE_INT val = streamer_read_hwi (&ib);
+ wide_int val = streamer_read_wide_int (&ib);
 
- if (do_warning != -1 || j > this_enum.vals.length ())
+ if (do_warning != -1 || j >= this_enum.vals.length ())
continue;
  if (strcmp (id, this_enum.vals[j].name)
  || val != this_enum.vals[j].val)
@@ -4175,13 +4192,19 @@ ipa_odr_read_section (struct lto_file_decl_data 
*file_data, const char *data,
  warn_name = xstrdup (id);
  warn_value = val;
  do_warning = j;
+ if (dump_file)
+   fprintf (dump_file, "  Different on entry %i\n", j);
}
}
- bitpack_d bp = streamer_read_bitpack (&ib);
 
+ /* Stream in locations, but do not apply them unless we are going
+to warn.  */
+ bitpack_d bp = streamer_read_bitpack (&ib);
  location_t locus;
+
  stream_input_location (&locus, &bp, data_in);
 
+ /* Did we find a di

[PATCH] avoid -Wmaybe-uninitialized in reload_cse_simplify_operands (PR bootstrap/95555)

2020-06-06 Thread Martin Sebor via Gcc-patches

A recent enhancement to the uninitialized access coverage to include
dynamically allocated objects, including alloca and VLAs, triggers
an expected instance of -Wmaybe-uninitialized on powerpc64-linux
in reload_cse_simplify_operands where an element of an XALLOCAVEC-
allocated array is read before it's provably assigned to.  With
-Werror this causes the bootstrap there to fail.

The attached patch avoids the warning by clearing the element first.

Although not necessary to avoid the warning, the patch also adds
an assert to verify that the array isn't accessed outside its bounds.
recog.c sets which_alternative to -1 in a couple of places and
a number of tests for it being equal to it so I added the assert
"just to be sure."

Tested on x86_64-linux (the warning was also confirmed gone on
powerpc64 by the reporter).

Martin
PR bootstrap/9 - powepc64 bootstrap failure due to -Wmaybe-uninitialized in reload_cse_simplify_operands

gcc/ChangeLog:

	* postreload.c (reload_cse_simplify_operands): Clear first array element
	before using it.  Assert a precondition.

diff --git a/gcc/postreload.c b/gcc/postreload.c
index f6258285022..c9e637500f1 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -592,6 +592,13 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
 	}
 }
 
+  /* The loop below sets alternative_order[0] but -Wmaybe-uninitialized
+ can't know that.  Clear it here to avoid the warning.  */
+  alternative_order[0] = 0;
+  gcc_assert (!recog_data.n_alternatives
+	  || (which_alternative >= 0
+		  && which_alternative < recog_data.n_alternatives));
+
   /* Record all alternatives which are better or equal to the currently
  matching one in the alternative_order array.  */
   for (i = j = 0; i < recog_data.n_alternatives; i++)


[PATCH] PR fortran/95091 - Buffer overflows with submodules and long symbols

2020-06-06 Thread Harald Anlauf
There's another case of buffer overflows when F2008 submodules are used.
Buffer sizes are further increased, and checks for overflow are put into
place.

OK for master?

I intend to backport to 10 and 9, since I believe the patch is safe.

Thanks,
Harald


PR fortran/95091 - Buffer overflows with submodules and long symbols

With submodules, name mangling results in long internal symbols.  This
requires adjustment of the sizes of temporaries to avoid buffer overflows.

2020-06-06  Harald Anlauf  

gcc/fortran/
PR fortran/95091
* class.c (get_unique_type_string, gfc_hash_value): Enlarge
buffers, and check whether the strings returned by
get_unique_type_string() fit.

diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index b1764073ab4..8bb73502f5d 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -509,9 +509,11 @@ get_unique_type_string (char *string, gfc_symbol *derived)
 static void
 get_unique_hashed_string (char *string, gfc_symbol *derived)
 {
-  /* Provide sufficient space to hold "symbol_Pdtsymbol".  */
-  char tmp[2*GFC_MAX_SYMBOL_LEN+5];
+  /* Provide sufficient space to hold "symbol.symbol_symbol".  */
+  char tmp[3*GFC_MAX_SYMBOL_LEN+3];
   get_unique_type_string (&tmp[0], derived);
+  size_t len = strnlen (tmp, sizeof (tmp));
+  gcc_assert (len < sizeof (tmp));
   /* If string is too long, use hash value in hex representation (allow for
  extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
  We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
@@ -532,12 +534,13 @@ unsigned int
 gfc_hash_value (gfc_symbol *sym)
 {
   unsigned int hash = 0;
-  /* Provide sufficient space to hold "symbol_Pdtsymbol".  */
-  char c[2*GFC_MAX_SYMBOL_LEN+5];
+  /* Provide sufficient space to hold "symbol.symbol_symbol".  */
+  char c[3*GFC_MAX_SYMBOL_LEN+3];
   int i, len;

   get_unique_type_string (&c[0], sym);
-  len = strlen (c);
+  len = strnlen (c, sizeof (c));
+  gcc_assert (len < sizeof (c));

   for (i = 0; i < len; i++)
 hash = (hash << 6) + (hash << 16) - hash + c[i];
diff --git a/gcc/testsuite/gfortran.dg/pr95091.f90 b/gcc/testsuite/gfortran.dg/pr95091.f90
new file mode 100644
index 000..1c48dca2f4a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr95091.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-options "-fsecond-underscore" }
+! PR fortran/95091 - ICE in gfc_hash_value
+
+module m2345678901234567890123456789012345678901234567890123456789_123
+  type t2345678901234567890123456789012345678901234567890123456789_123
+  end type t2345678901234567890123456789012345678901234567890123456789_123
+  interface
+ module subroutine s2345678901234567890123456789012345678901234567890123456789_123 &
+  (x2345678901234567890123456789012345678901234567890123456789_123)
+end
+  end interface
+end
+submodule(m2345678901234567890123456789012345678901234567890123456789_123) &
+ n2345678901234567890123456789012345678901234567890123456789_123
+  type, extends(t2345678901234567890123456789012345678901234567890123456789_123) :: &
+u2345678901234567890123456789012345678901234567890123456789_123
+  end type
+end


[PATCH] Add support for C++20 barriers

2020-06-06 Thread Thomas Rodgers
* include/Makefile.am (std_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/std/barrier: New file.
* testsuite/30_thread/barrier/1.cc: New test.
* testsuite/30_thread/barrier/2.cc: Likewise.
* testsuite/30_thread/barrier/arrive_and_drop.cc: Likewise.
* testsuite/30_thread/barrier/arrive_and_wait.cc: Likewise.
* testsuite/30_thread/barrier/arrive.cc: Likewise.
* testsuite/30_thread/barrier/completion.cc: Likewise.
* testsuite/30_thread/barrier/max.cc: Likewise.
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/bits/atomic_base.h   |  15 +-
 libstdc++-v3/include/std/barrier  | 230 ++
 libstdc++-v3/include/std/version  |   5 +-
 .../testsuite/30_threads/barrier/1.cc |  27 ++
 .../testsuite/30_threads/barrier/2.cc |  27 ++
 .../testsuite/30_threads/barrier/arrive.cc|  34 +++
 .../30_threads/barrier/arrive_and_drop.cc |  32 +++
 .../30_threads/barrier/arrive_and_wait.cc |  33 +++
 .../30_threads/barrier/completion.cc  |  39 +++
 .../testsuite/30_threads/barrier/max.cc   |  26 ++
 12 files changed, 465 insertions(+), 5 deletions(-)
 create mode 100644 libstdc++-v3/include/std/barrier
 create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/1.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/2.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/arrive.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/arrive_and_drop.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/arrive_and_wait.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/completion.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/barrier/max.cc

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index b3ac1a3365f..e2cded53779 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -30,6 +30,7 @@ std_headers = \
${std_srcdir}/any \
${std_srcdir}/array \
${std_srcdir}/atomic \
+   ${std_srcdir}/barrier \
${std_srcdir}/bit \
${std_srcdir}/bitset \
${std_srcdir}/charconv \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index e73ff8b3e64..8e1163e8e18 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -375,6 +375,7 @@ std_headers = \
${std_srcdir}/any \
${std_srcdir}/array \
${std_srcdir}/atomic \
+   ${std_srcdir}/barrier \
${std_srcdir}/bit \
${std_srcdir}/bitset \
${std_srcdir}/charconv \
diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index 68d9e7e3756..271656c6b37 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -566,13 +566,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 #if __cplusplus > 201703L
+  template
+   _GLIBCXX_ALWAYS_INLINE void
+   _M_wait(__int_type __old, _Pred&& __pred,
+   memory_order __m) const noexcept
+   {
+ std::__atomic_wait(&_M_i, __old,
+std::forward<_Pred&&>(__pred));
+   }
+
   _GLIBCXX_ALWAYS_INLINE void
   wait(__int_type __old,
  memory_order __m = memory_order_seq_cst) const noexcept
   {
-   std::__atomic_wait(&_M_i, __old,
-  [__m, this, __old]()
-  { return this->load(__m) != __old; });
+   _M_wait(__old, [__m, this, __old]()
+   { return this->load(__m) != __old; },
+   __m);
   }
 
   // TODO add const volatile overload
diff --git a/libstdc++-v3/include/std/barrier b/libstdc++-v3/include/std/barrier
new file mode 100644
index 000..870db7db2ac
--- /dev/null
+++ b/libstdc++-v3/include/std/barrier
@@ -0,0 +1,230 @@
+//  -*- C++ -*-
+// This implementation is based on libcxx/include/barrier
+//===-- barrier.h --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===---===//
+
+#ifndef _GLIBCXX_BARRIER
+#define _GLIBCXX_BARRIER 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+#define __cpp_lib_barrier 201907L
+
+#include 
+
+#if defined(_GLIBCXX_HAS_GTHREADS)
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  struct __empty_completion
+  {
+_GLIBCXX_ALWAYS_INLINE void
+operator()() noexcept
+{ }
+  };
+
+/*
+
+The default implementation of __barrier_base is a classic tr

[PATCH] Add C++2a synchronization support

2020-06-06 Thread Thomas Rodgers
Add support for -
atomic wait/notify_one/notify_all
counting_semaphore
binary_semaphore
latch

* include/Makefile.am (bits_headers): Add new header.
* include/Makefile.in: Regenerate.
* include/bits/atomic_base.h (__atomic_base<_Itp>::wait): Define.
(__atomic_base<_Itp>::notify_one): Likewise.
(__atomic_base<_Itp>::notify_all): Likewise.
(__atomic_base<_Ptp*>::wait): Likewise.
(__atomic_base<_Ptp*>::notify_one): Likewise.
(__atomic_base<_Ptp*>::notify_all): Likewise.
(__atomic_impl::wait): Likewise.
(__atomic_impl::notify_one): Likewise.
(__atomic_impl::notify_all): Likewise.
(__atomic_float<_Fp>::wait): Likewise.
(__atomic_float<_Fp>::notify_one): Likewise.
(__atomic_float<_Fp>::notify_all): Likewise.
(__atomic_ref<_Tp>::wait): Likewise.
(__atomic_ref<_Tp>::notify_one): Likewise.
(__atomic_ref<_Tp>::notify_all): Likewise.
(atomic_wait<_Tp>): Likewise.
(atomic_wait_explicit<_Tp>): Likewise.
(atomic_notify_one<_Tp>): Likewise.
(atomic_notify_all<_Tp>): Likewise.
* include/bits/atomic_wait.h: New file.
* include/bits/atomic_timed_wait.h: New file.
* include/bits/semaphore_base.h: New file.
* include/std/atomic (atomic::wait): Define.
(atomic::wait_one): Likewise.
(atomic::wait_all): Likewise.
(atomic<_Tp>::wait): Likewise.
(atomic<_Tp>::wait_one): Likewise.
(atomic<_Tp>::wait_all): Likewise.
(atomic<_Tp*>::wait): Likewise.
(atomic<_Tp*>::wait_one): Likewise.
(atomic<_Tp*>::wait_all): Likewise.
* include/std/latch: New file.
* include/std/semaphore: New file.
* include/std/version: Add __cpp_lib_semaphore and
__cpp_lib_latch defines.
* testsuite/29_atomic/atomic/wait_notify/atomic_refs.cc: New test.
* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
* testsuite/30_thread/semaphore/1.cc: New test.
* testsuite/30_thread/semaphore/2.cc: Likewise.
* testsuite/30_thread/semaphore/least_max_value_neg.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire_for.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire_futex.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire_posix.cc: Likewise.
* testsuite/30_thread/semaphore/try_acquire_until.cc: Likewise.
* testsuite/30_thread/latch/1.cc: New test.
* testsuite/30_thread/latch/2.cc: New test.
* testsuite/30_thread/latch/3.cc: New test.
---
 libstdc++-v3/include/Makefile.am  |   5 +
 libstdc++-v3/include/Makefile.in  |   5 +
 libstdc++-v3/include/bits/atomic_base.h   | 161 +-
 libstdc++-v3/include/bits/atomic_timed_wait.h | 282 +
 libstdc++-v3/include/bits/atomic_wait.h   | 291 ++
 libstdc++-v3/include/bits/semaphore_base.h| 272 
 libstdc++-v3/include/std/atomic   |  61 
 libstdc++-v3/include/std/latch|  90 ++
 libstdc++-v3/include/std/semaphore|  86 ++
 libstdc++-v3/include/std/version  |   2 +
 .../atomic/wait_notify/atomic_refs.cc | 103 +++
 .../29_atomics/atomic/wait_notify/bool.cc |  59 
 .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
 .../29_atomics/atomic/wait_notify/generic.h   |  88 ++
 .../atomic/wait_notify/integrals.cc   |  56 
 .../29_atomics/atomic/wait_notify/pointers.cc |  59 
 libstdc++-v3/testsuite/30_threads/latch/1.cc  |  27 ++
 libstdc++-v3/testsuite/30_threads/latch/2.cc  |  27 ++
 libstdc++-v3/testsuite/30_threads/latch/3.cc  |  50 +++
 .../testsuite/30_threads/semaphore/1.cc   |  27 ++
 .../testsuite/30_threads/semaphore/2.cc   |  27 ++
 .../semaphore/least_max_value_neg.cc  |  28 ++
 .../30_threads/semaphore/try_acquire.cc   |  55 
 .../30_threads/semaphore/try_acquire_for.cc   |  85 +
 .../30_threads/semaphore/try_acquire_futex.cc |  51 +++
 .../30_threads/semaphore/try_acquire_posix.cc | 169 ++
 .../30_threads/semaphore/try_acquire_until.cc |  94 ++
 27 files changed, 2291 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/include/bits/atomic_timed_wait.h
 create mode 100644 libstdc++-v3/include/bits/atomic_wait.h
 create mode 100644 libstdc++-v3/include/bits/semaphore_base.h
 create mode 100644 libstdc++-v3/include/std/latch
 create mode 100644 libstdc++-v3/include/std/semaphore
 create mode 100644 
libstdc++-v3/

[PATCH 3/4] Adjust wait logic to limit spurious eval of wait predicate.

2020-06-06 Thread Thomas Rodgers
* include/bits/atomic_wait.h (__waiters::_M_do_wait): adjust wakeup
  logic.
---
 libstdc++-v3/include/bits/atomic_wait.h | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_wait.h 
b/libstdc++-v3/include/bits/atomic_wait.h
index 92c1e2526ed..cce11ae1cf5 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -138,24 +138,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
   void
-  _M_do_wait(__platform_wait_t __version) noexcept
+  _M_do_wait(__platform_wait_t __old) noexcept
   {
+   __platform_wait_t __cur;
+   __atomic_load(&_M_ver, &__cur, __ATOMIC_ACQUIRE);
+   while (__cur == __old)
+ {
 #ifdef _GLIBCXX_HAVE_LINUX_FUTEX
-   __platform_wait(&_M_ver, __version);
+   __platform_wait(&_M_ver, __cur);
 #else
-   __platform_wait_t __cur = 0;
-   while (__cur <= __version)
- {
__waiters::__lock_t __l(_M_mtx);
auto __e = __gthread_cond_wait(&_M_cv, 
__l.mutex()->native_handle());
if (__e)
  std::terminate();
-   __platform_wait_t __last = __cur;
+#endif
__atomic_load(&_M_ver, &__cur, __ATOMIC_ACQUIRE);
-   if (__cur < __last)
- break; // break the loop if version overflows
  }
-#endif
   }
 
   __platform_wait_t
-- 
2.26.2



[PATCH] Remove binary_semaphore implementation from stop_token

2020-06-06 Thread Thomas Rodgers
* include/std/stop_token: Remove local binary_semaphore implementation.
  (_Stop_state_t::_M_do_try_lock): Use __thread_yield() from
  bits/atomic_wait.h.
---
 libstdc++-v3/include/std/stop_token | 40 ++---
 1 file changed, 2 insertions(+), 38 deletions(-)

diff --git a/libstdc++-v3/include/std/stop_token 
b/libstdc++-v3/include/std/stop_token
index 847d12f7454..40a71574a7e 100644
--- a/libstdc++-v3/include/std/stop_token
+++ b/libstdc++-v3/include/std/stop_token
@@ -36,9 +36,7 @@
 #ifdef _GLIBCXX_HAS_GTHREADS
 # define __cpp_lib_jthread 201911L
 # include 
-# if __has_include()
-#  include 
-# endif
+# include 
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -100,40 +98,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 template
   friend class stop_callback;
 
-static void
-_S_yield() noexcept
-{
-#if defined __i386__ || defined __x86_64__
-  __builtin_ia32_pause();
-#elif defined _GLIBCXX_USE_SCHED_YIELD
-  __gthread_yield();
-#endif
-}
-
-#ifndef __cpp_lib_semaphore
-// TODO: replace this with a real implementation of std::binary_semaphore
-struct binary_semaphore
-{
-  explicit binary_semaphore(int __d) : _M_counter(__d > 0) { }
-
-  void release() { _M_counter.fetch_add(1, memory_order::release); }
-
-  void acquire()
-  {
-   int __old = 1;
-   while (!_M_counter.compare_exchange_weak(__old, 0,
-memory_order::acquire,
-memory_order::relaxed))
- {
-   __old = 1;
-   _S_yield();
- }
-  }
-
-  atomic _M_counter;
-};
-#endif
-
 struct _Stop_cb
 {
   using __cb_type = void(_Stop_cb*) noexcept;
@@ -389,7 +353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
if (__curval & _S_locked_bit)
  {
-   _S_yield();
+   __detail::__thread_yield();
__curval = _M_value.load(__failure);
return false;
  }
-- 
2.26.2



Re: [PATCH] hurd: libgcc unwinding support over signal trampolines

2020-06-06 Thread Samuel Thibault
Hello,

Any news on this?

Samuel

Samuel Thibault, le ven. 29 mai 2020 13:46:50 +0200, a ecrit:
> Hello,
> 
> libgcc is currently missing the support for unwinding over signal
> trampolines on GNU/Hurd. The attached patch implements it.
> 
> Samuel

> hurd: libgcc unwinding support over signal trampolines
> 
> * libgcc/config.host (md_unwind_header): Set to i386/gnu-unwind.h on
> i[34567]86-*-gnu*.
> * src/libgcc/config/i386/gnu-unwind.h: New file.
> 
> diff --git a/libgcc/config.host b/libgcc/config.host
> index 2cd42097167..044b34d53cc 100644
> --- a/libgcc/config.host
> +++ b/libgcc/config.host
> @@ -734,11 +734,17 @@ i[34567]86-*-linux*)
>   tm_file="${tm_file} i386/elf-lib.h"
>   md_unwind_header=i386/linux-unwind.h
>   ;;
> -i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-gnu* | 
> i[34567]86-*-kopensolaris*-gnu)
> +i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-kopensolaris*-gnu)
>   extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o 
> crtfastmath.o"
>   tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff 
> t-dfprules"
>   tm_file="${tm_file} i386/elf-lib.h"
>   ;;
> +i[34567]86-*-gnu*)
> + extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o 
> crtfastmath.o"
> + tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff 
> t-dfprules"
> + tm_file="${tm_file} i386/elf-lib.h"
> + md_unwind_header=i386/gnu-unwind.h
> + ;;
>  x86_64-*-linux*)
>   extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o 
> crtfastmath.o"
>   tmake_file="${tmake_file} i386/t-crtpc t-crtfm i386/t-crtstuff 
> t-dfprules"
> diff --git a/src/libgcc/config/i386/gnu-unwind.h 
> b/src/libgcc/config/i386/gnu-unwind.h
> new file mode 100644
> index 000..db47f0ac1d4
> --- /dev/null
> +++ b/src/libgcc/config/i386/gnu-unwind.h
> @@ -0,0 +1,107 @@
> +/* DWARF2 EH unwinding support for GNU Hurd: x86.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   Contributed by Samuel Thibault 
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +Under Section 7 of GPL version 3, you are granted additional
> +permissions described in the GCC Runtime Library Exception, version
> +3.1, as published by the Free Software Foundation.
> +
> +You should have received a copy of the GNU General Public License and
> +a copy of the GCC Runtime Library Exception along with this program;
> +see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> +.  */
> +
> +/* Do code reading to identify a signal frame, and set the frame
> +   state data appropriately.  See unwind-dw2.c for the structs. */
> +
> +#ifndef inhibit_libc
> +
> +#include 
> +
> +#define MD_FALLBACK_FRAME_STATE_FOR x86_gnu_fallback_frame_state
> +
> +static _Unwind_Reason_Code
> +x86_gnu_fallback_frame_state
> +(struct _Unwind_Context *context, _Unwind_FrameState *fs)
> +{
> +  struct handler_args {
> +int signo;
> +int sigcode;
> +struct sigcontext *scp;
> +  } *handler_args;
> +  struct sigcontext *scp;
> +  unsigned long usp;
> +
> +/*
> + * i386 sigtramp frame we are looking for follows.
> + * (see glibc/sysdeps/mach/hurd/i386/trampoline.c assembly)
> + *
> + * rpc_wait_trampoline:
> + *   0:  b8 e7 ff ff ff  mov$-25,%eax   mach_msg_trap
> + *   5:  9a 00 00 00 00 07 00lcall  $7,$0
> + *  12:  89 01   movl   %eax, (%ecx)
> + *  14:  89 dc   movl   %ebx, %esp  switch to signal 
> stack
> + *
> + * trampoline:
> + *  16:  ff d2   call   *%edx   call the handler 
> function
> + * RA HERE
> + *  18:  83 c4 0caddl   $12, %esp   pop its args
> + *  21:  c3  retreturn to 
> sigreturn
> + *
> + * firewall:
> + *  22:  f4  hlt
> + */
> +
> +  if (!(   *(unsigned int   *)(context->ra ) == 0xc30cc483
> +&& *(unsigned char  *)(context->ra +  4) ==   0xf4
> +
> +&& *(unsigned int   *)(context->ra -  4) == 0xd2ffdc89
> +&& *(unsigned int   *)(context->ra -  8) == 0x01890007
> +&& *(unsigned int   *)(context->ra - 12) == 0x
> +&& *(unsigned int   *)(context->ra - 16) == 0x9aff
> +&& *(unsigned short *)(context->ra - 18) == 0xe7b8))
> +return _URC_END_OF_STACK;
> +
> +  handler_args = context->cfa;
> +  scp = handler_args->scp;
> +  usp = scp->sc_uesp;
> +
> +  fs->regs.cfa_how = CFA_REG_OFFSET;
> +  fs->regs.cfa_reg = 4;
> +  fs->r