[PATCH] Put __dso_handle in .sdata/.sbss on ia64

2019-06-01 Thread James Clarke
The symbol is exposed to C by dso_handle.h, and since it's a single
8-byte pointer, it is just within the threshold for being in the small
data (or bss) section, so code accessing it will use GP-relative
addressing. Therefore we must put it in .sdata/.sbss in case our other
data sections grow too big and we overflow the 22-bit relocation.

libgcc/
* config/ia64/crtbegin.S (__dso_handle): Put in .sdata/.sbss
rather than .data/.bss so it can be accessed via gp-relative
addressing.
---
 libgcc/config/ia64/crtbegin.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgcc/config/ia64/crtbegin.S b/libgcc/config/ia64/crtbegin.S
index 5b2f55936dd..213ccd7ab8b 100644
--- a/libgcc/config/ia64/crtbegin.S
+++ b/libgcc/config/ia64/crtbegin.S
@@ -45,11 +45,11 @@ dtor_ptr:
.type __dso_handle,@object
.size __dso_handle,8
 #ifdef SHARED
-   .section .data
+   .section .sdata
 __dso_handle:
data8   __dso_handle
 #else
-   .section .bss
+   .section .sbss
.align 8
 __dso_handle:
.skip   8
-- 
2.20.1



[Darwin, x86, testsuite] Adjust tests for Darwin PR90698.

2019-06-01 Thread Iain Sandoe
Darwin doesn't have support for -mcmodel={medium, large, kernel} so we don't
expect tests for those things to work.

For now mark them as xfail where possible and skip where that isn't.
These changes will be logged onto the PR and therefore can be backed
out when the facility is implemented.

tested on x86_64-darwin16 and x86_64-linux-gnu 
(--target_board=unix\{-m32,-m64\}\{,-fpic\})

applied to mainline,
thanks
Iain

gcc/testsuite/ChangeLog:

2019-06-01  Iain Sandoe  

PR target/90698
* gcc.target/i386/pr49866.c: XFAIL for Darwin.
* gcc.target/i386/pr63538.c: Likewise.
* gcc.target/i386/pr61599-1.c: Skip for Darwin.

diff --git a/gcc/testsuite/gcc.target/i386/pr49866.c 
b/gcc/testsuite/gcc.target/i386/pr49866.c
index 622c8f6..7c80f13 100644
--- a/gcc/testsuite/gcc.target/i386/pr49866.c
+++ b/gcc/testsuite/gcc.target/i386/pr49866.c
@@ -1,5 +1,6 @@
 /* PR target/49866 */
 /* { dg-do assemble { target lp64 } } */
+/* { dg-xfail-if "PR90698" { *-*-darwin* } } */
 /* { dg-options "-O2 -mcmodel=large"  } */
 
 void fn (void *, int, int);
diff --git a/gcc/testsuite/gcc.target/i386/pr61599-1.c 
b/gcc/testsuite/gcc.target/i386/pr61599-1.c
index 71b1c2f..52fea39 100644
--- a/gcc/testsuite/gcc.target/i386/pr61599-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr61599-1.c
@@ -1,5 +1,6 @@
 /* PR target/61599 */
 /* { dg-do run { target lp64 } } */
+/* { dg-skip-if "PR90698" { *-*-darwin* } } */
 /* { dg-additional-sources pr61599-2.c } */
 /* { dg-options "-mcmodel=medium -fdata-sections" } */
 
diff --git a/gcc/testsuite/gcc.target/i386/pr63538.c 
b/gcc/testsuite/gcc.target/i386/pr63538.c
index 7b979c3..87d5d3e 100644
--- a/gcc/testsuite/gcc.target/i386/pr63538.c
+++ b/gcc/testsuite/gcc.target/i386/pr63538.c
@@ -9,5 +9,5 @@ char *foo ()
 {
   return str;
 }
-
-/* { dg-final { scan-assembler "movabs" } } */
+/* See PR90698 re. Darwin xfail.  */
+/* { dg-final { scan-assembler "movabs" { xfail { *-*-darwin* } } } } */



Re: Test for C++20 p0858 - ConstexprIterator requirements.

2019-06-01 Thread Ville Voutilainen
On Sat, 1 Jun 2019 at 22:40, Ed Smith-Rowland <3dw...@verizon.net> wrote:

> Ok, third time's a charm.
>
> I was brain dead about the constexpr patch.?? I'm now setting a constexpr
> variable from test() in a caller.

Looks good. Jonathan needs to approve it, though.

> But static_assert is a constexpr context no?

Yes, it is. It's just that now all of test() is verified to be okay as
a constant expression, including std::copy.


Re: Test for C++20 p0858 - ConstexprIterator requirements.

2019-06-01 Thread Ed Smith-Rowland via gcc-patches

On 6/1/19 2:42 PM, Ville Voutilainen wrote:

On Sat, 1 Jun 2019 at 21:09, Ed Smith-Rowland <3dw...@verizon.net> wrote:

On 5/31/19 6:29 PM, Ville Voutilainen wrote:

On Sat, 1 Jun 2019 at 01:24, Ed Smith-Rowland via libstdc++
 wrote:

Greetings,

Iterators for  and  are usabe in a constexpr context
since C++2017.

This just adds a compile test to make sure and check a box for C++20
p0858 - ConstexprIterator requirements.

Those tests don't use the iterators in a constexpr context. To do
that, maybe do those std::copy operations
in a constexpr function and then initialize a constexpr variable with
the result of a call to that function?

Thanks Ville,

I had completely forgotten to make these test functions constexpr - FIXED.

.but that doesn't enforce a constexpr context. If you add another
function that calls these functions
and initializes a constexpr variable, then we have the enforcement I
seek. Such as

void test2()
{
 constexpr char x = test();
}


Ok, third time's a charm.

I was brain dead about the constexpr patch.?? I'm now setting a constexpr 
variable from test() in a caller.


But static_assert is a constexpr context no?

Ed


2019-06-03  Edward Smith-Rowland  <3dw...@verizon.net>

Test for C++20 p0858 - ConstexprIterator requirements.
* testsuite/21_strings/basic_string_view/requirements/constexpr_iter.cc:
New test.
* testsuite/23_containers/array/requirements/constexpr_iter.cc:
New test.

Index: testsuite/21_strings/basic_string_view/requirements/constexpr_iter.cc
===
--- testsuite/21_strings/basic_string_view/requirements/constexpr_iter.cc   
(nonexistent)
+++ testsuite/21_strings/basic_string_view/requirements/constexpr_iter.cc   
(working copy)
@@ -0,0 +1,43 @@
+// { dg-do compile { target c++2a } }
+//
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+#include 
+#include 
+
+constexpr char
+test()
+{
+  constexpr std::string_view hw("Hello, World!");
+  static_assert('H' == *hw.begin());
+  auto ch = hw[4];
+  static_assert('W' == *(hw.cbegin() + 7));
+
+#if __cplusplus > 201703L
+  std::array a2{{0,0,0,0,0,0,0,0,0,0,0,0,0}};
+  std::copy(hw.begin(), hw.end(), a2.begin());
+#endif
+
+  return *(hw.cbegin() + 3);
+}
+
+void
+run_test()
+{
+  constexpr char ch = test();
+}
Index: testsuite/23_containers/array/requirements/constexpr_iter.cc
===
--- testsuite/23_containers/array/requirements/constexpr_iter.cc
(nonexistent)
+++ testsuite/23_containers/array/requirements/constexpr_iter.cc
(working copy)
@@ -0,0 +1,42 @@
+// { dg-do compile { target c++2a } }
+//
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+#include 
+
+constexpr int
+test()
+{
+  constexpr std::array a1{{1, 2, 3}};
+  static_assert(1 == *a1.begin());
+  auto n = a1[0] * a1[1]* a1[2];
+  static_assert(1 == *a1.cbegin());
+
+#if __cplusplus > 201703L
+  std::array a2{{0, 0, 0}};
+  std::copy(a1.begin(), a1.end(), a2.begin());
+#endif
+
+  return n;
+}
+
+void
+run_test()
+{
+  constexpr int n = test();
+}


Re: Test for C++20 p0858 - ConstexprIterator requirements.

2019-06-01 Thread Ville Voutilainen
On Sat, 1 Jun 2019 at 21:09, Ed Smith-Rowland <3dw...@verizon.net> wrote:
>
> On 5/31/19 6:29 PM, Ville Voutilainen wrote:
> > On Sat, 1 Jun 2019 at 01:24, Ed Smith-Rowland via libstdc++
> >  wrote:
> >> Greetings,
> >>
> >> Iterators for  and  are usabe in a constexpr context
> >> since C++2017.
> >>
> >> This just adds a compile test to make sure and check a box for C++20
> >> p0858 - ConstexprIterator requirements.
> >
> > Those tests don't use the iterators in a constexpr context. To do
> > that, maybe do those std::copy operations
> > in a constexpr function and then initialize a constexpr variable with
> > the result of a call to that function?
>
> Thanks Ville,
>
> I had completely forgotten to make these test functions constexpr - FIXED.

..but that doesn't enforce a constexpr context. If you add another
function that calls these functions
and initializes a constexpr variable, then we have the enforcement I
seek. Such as

void test2()
{
constexpr char x = test();
}


Re: Test for C++20 p0858 - ConstexprIterator requirements.

2019-06-01 Thread Ed Smith-Rowland via gcc-patches

On 5/31/19 6:29 PM, Ville Voutilainen wrote:

On Sat, 1 Jun 2019 at 01:24, Ed Smith-Rowland via libstdc++
 wrote:

Greetings,

Iterators for  and  are usabe in a constexpr context
since C++2017.

This just adds a compile test to make sure and check a box for C++20
p0858 - ConstexprIterator requirements.


Those tests don't use the iterators in a constexpr context. To do
that, maybe do those std::copy operations
in a constexpr function and then initialize a constexpr variable with
the result of a call to that function?


Thanks Ville,

I had completely forgotten to make these test functions constexpr - FIXED.

Also, instead of bool variables I put the checks in static_asserts.

I return functions of (derefed) iterators.

I made it so we could run these at C++17 if we want to with '#if 
__cplusplus == 201703L' the algorithm usage for C++20 only.?? This wasn't 
a DR though.


Anyway, that should do it.

Built and tested clean on x86_64-linux. Ok?

Ed


2019-06-03  Edward Smith-Rowland  <3dw...@verizon.net>

Test for C++20 p0858 - ConstexprIterator requirements.
* testsuite/21_strings/basic_string_view/requirements/constexpr_iter.cc:
New test.
* testsuite/23_containers/array/requirements/constexpr_iter.cc:
New test.

Index: testsuite/21_strings/basic_string_view/requirements/constexpr_iter.cc
===
--- testsuite/21_strings/basic_string_view/requirements/constexpr_iter.cc   
(nonexistent)
+++ testsuite/21_strings/basic_string_view/requirements/constexpr_iter.cc   
(working copy)
@@ -0,0 +1,37 @@
+// { dg-do compile { target c++2a } }
+//
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+#include 
+#include 
+
+constexpr char
+test()
+{
+  constexpr std::string_view hw("Hello, World!");
+  static_assert('H' == *hw.begin());
+  auto ch = hw[4];
+  static_assert('W' == *(hw.cbegin() + 7));
+
+#if __cplusplus > 201703L
+  std::array a2{{0,0,0,0,0,0,0,0,0,0,0,0,0}};
+  std::copy(hw.begin(), hw.end(), a2.begin());
+#endif
+
+  return *(hw.cbegin() + 3);
+}
Index: testsuite/23_containers/array/requirements/constexpr_iter.cc
===
--- testsuite/23_containers/array/requirements/constexpr_iter.cc
(nonexistent)
+++ testsuite/23_containers/array/requirements/constexpr_iter.cc
(working copy)
@@ -0,0 +1,36 @@
+// { dg-do compile { target c++2a } }
+//
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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.
+//
+// This library 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.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+#include 
+
+constexpr int
+test()
+{
+  constexpr std::array a1{{1, 2, 3}};
+  static_assert(1 == *a1.begin());
+  auto n = a1[0] * a1[1]* a1[2];
+  static_assert(1 == *a1.cbegin());
+
+#if __cplusplus > 201703L
+  std::array a2{{0, 0, 0}};
+  std::copy(a1.begin(), a1.end(), a2.begin());
+#endif
+
+  return n;
+}


[PATCH v2] PR71482: Add -Wglobal-constructors

2019-06-01 Thread Sean Gillespie
This adds a new warning, -Wglobal-constructors, that warns whenever a
decl requires a global constructor or destructor. Global destructors are
required whenever a decl with thread_local or global storage is declared
with a type with a nontrivial destructor. Global constructors are required
whenever a declaration's initializer is a non-trivial, non-constant
initializtion.

This warning mirrors the Clang option -Wglobal-constructors, which warns
on the same thing. -Wglobal-constructors was present in Apple's GCC and
later made its way into Clang.

Bootstrapped and regression-tested on x86-64 linux, new tests passing.

gcc/ChangeLog:

2019-05-28  Sean Gillespie  

PR c++/71482
* doc/invoke.texi: Add new flag -Wglobal-constructors.

gcc/c-family/ChangeLog:

2019-05-28  Sean Gillespie  

PR c++/71482
* c.opt: Add new flag -Wglobal-constructors.

gcc/cp/ChangeLog:

2019-05-28  Sean Gillespie  

PR c++/71482
* decl.c (expand_static_init): Warn if a thread local or static decl
requires a non-trivial constructor or destructor.

gcc/testsuite/ChangeLog:

2019-05-28  Sean Gillespie  

PR c++/71482
* g++.dg/warn/global-constructors-1.C: New test.
* g++.dg/warn/global-constructors-2.C: New test.
---
 gcc/c-family/c.opt|  4 ++
 gcc/cp/decl.c | 22 ++--
 gcc/doc/invoke.texi   | 35 
 .../g++.dg/warn/global-constructors-1.C   | 53 +++
 .../g++.dg/warn/global-constructors-2.C   | 49 +
 5 files changed, 159 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/global-constructors-1.C
 create mode 100644 gcc/testsuite/g++.dg/warn/global-constructors-2.C

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 046d489f7eb..21f12d4f7b2 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -613,6 +613,10 @@ Wformat-truncation=
 C ObjC C++ LTO ObjC++ Joined RejectNegative UInteger Var(warn_format_trunc) 
Warning LangEnabledBy(C ObjC C++ LTO ObjC++,Wformat=, warn_format >= 1, 0) 
IntegerRange(0, 2)
 Warn about calls to snprintf and similar functions that truncate output.
 
+Wglobal-constructors
+C++ ObjC++ Var(warn_global_constructors) Warning
+Warn about objects with static storage duration that require dynamic 
initialization or have nontrivial destructors.
+
 Wif-not-aligned
 C ObjC C++ ObjC++ Var(warn_if_not_aligned) Init(1) Warning
 Warn when the field in a struct is not aligned.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 19d14a6a5e9..8dc366aa0c6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8324,10 +8324,10 @@ expand_static_init (tree decl, tree init)
return;
 }
 
+  location_t dloc = DECL_SOURCE_LOCATION (decl);
   if (CP_DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
   && !DECL_FUNCTION_SCOPE_P (decl))
 {
-  location_t dloc = DECL_SOURCE_LOCATION (decl);
   if (init)
error_at (dloc, "non-local variable %qD declared %<__thread%> "
  "needs dynamic initialization", decl);
@@ -8467,10 +8467,24 @@ expand_static_init (tree decl, tree init)
   finish_then_clause (if_stmt);
   finish_if_stmt (if_stmt);
 }
-  else if (CP_DECL_THREAD_LOCAL_P (decl))
-tls_aggregates = tree_cons (init, decl, tls_aggregates);
   else
-static_aggregates = tree_cons (init, decl, static_aggregates);
+{
+  if (CP_DECL_THREAD_LOCAL_P (decl))
+tls_aggregates = tree_cons (init, decl, tls_aggregates);
+  else
+static_aggregates = tree_cons (init, decl, static_aggregates);
+
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+{
+  warning_at (dloc, OPT_Wglobal_constructors,
+"declaration requires a global destructor");
+  return;
+}
+
+  if (DECL_NONTRIVIALLY_INITIALIZED_P (decl) && !decl_constant_var_p 
(decl))
+warning_at (dloc, OPT_Wglobal_constructors,
+  "declaration requires a global constructor");
+}
 }
 
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4964cc41ba3..77d324584ec 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -312,6 +312,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wformat-security  -Wformat-signedness  -Wformat-truncation=@var{n} @gol
 -Wformat-y2k  -Wframe-address @gol
 -Wframe-larger-than=@var{byte-size}  -Wno-free-nonheap-object @gol
+-Wglobal-constructors @gol
 -Wjump-misses-init @gol
 -Whsa  -Wif-not-aligned @gol
 -Wignored-qualifiers  -Wignored-attributes  -Wincompatible-pointer-types @gol
@@ -6509,6 +6510,40 @@ to @option{-Wframe-larger-than=}@samp{SIZE_MAX} or 
larger.
 Do not warn when attempting to free an object that was not allocated
 on the heap.
 
+@item -Wglobal-constructors @r{(C++ and Objective-C++ only)}
+@opindex Wglobal-constructors
+@opindex Wno-global-constructors
+Warn whenever an object with static storage duration either requires dynamic
+init

Improve alias info on incomplete ODR pointers

2019-06-01 Thread Jan Hubicka
Hi,
while looking at the cases disambiguated by access path and not by alias simple
alias set lookup I noticed that there are number of accesses to pointers of
different type which we consider as possible equivalent.

For example

struct a *a;
struct b *b;

is currently considered aliasing with LTO if one of the structures is
incomplete.  For C++ sources we could fix this by looking up the complete
variant via ODR type hash.

Note that this is also safe WRT subset construction for aggregates because
we glob all pointers to void * with LTO prior calling get_alias_set (so 
currently any two structures containing pointer conflict with each other).

This quite simple patch saves about 5% of void * globbing when compiling
cc1plus with LTO.

Stats change from:

Alias oracle query stats:   
  refs_may_alias_p: 39482421 disambiguations, 47760976 queries  
  ref_maybe_used_by_call_p: 58817 disambiguations, 40085376 queries 
  call_may_clobber_ref_p: 5579 disambiguations, 8373 queries
  aliasing_component_ref_p: 99652 disambiguations, 285661 queries   
  TBAA oracle: 11408132 disambiguations 35099843 queries
   14285452 are in alias set 0  
   5370901 queries asked about the same object  
   147 queries asked about the same alias set   
   0 access volatile
   1721512 are dependent in the DAG 
   2313699 are aritificially in conflict with void *

PTA query stats:
  pt_solution_includes: 474714 disambiguations, 7173966 queries 
  pt_solutions_intersect: 390271 disambiguations, 7304940 queries   

To:

Alias oracle query stats:   
  refs_may_alias_p: 39461257 disambiguations, 47717872 queries  
  ref_maybe_used_by_call_p: 58819 disambiguations, 40064384 queries 
  call_may_clobber_ref_p: 5579 disambiguations, 8373 queries
  aliasing_component_ref_p: 91509 disambiguations, 277156 queries   
  TBAA oracle: 11436147 disambiguations 34996771 queries
   14283553 are in alias set 0  
   5389241 queries asked about the same object  
   147 queries asked about the same alias set   
   0 access volatile
   1694396 are dependent in the DAG 
   2193287 are aritificially in conflict with void *

PTA query stats:
  pt_solution_includes: 474052 disambiguations, 7165766 queries 
  pt_solutions_intersect: 389420 disambiguations, 7268793 queries   

Bootstrapped/regtested x86_64-linux, comitted.

Honza

* alias.c: Include ipa-utils.h.
(get_alias_set): Try to complete ODR type via ODR type hash lookup.
* ipa-devirt.c (prevailing_odr_type): New.
* ipa-utils.h (previaling_odr_type): Declare.

* g++.dg/lto/alias-1_0.C: New testcase.
* g++.dg/lto/alias-1_1.C: New testcase.
Index: alias.c
===
--- alias.c (revision 271836)
+++ alias.c (working copy)
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.
 #include "cfganal.h"
 #include "rtl-iter.h"
 #include "cgraph.h"
+#include "ipa-utils.h"
 
 /* The aliasing API provided here solves related but different problems:
 
@@ -1008,6 +1009,14 @@ get_alias_set (tree t)
}
   p = TYPE_MAIN_VARIANT (p);
 
+  /* In LTO for C++ programs we can turn in complete types to complete
+using ODR name lookup.  */
+  if (in_lto_p && TYPE_STRUCTURAL_EQUALITY_P (p) && odr_type_p (p))
+   {
+ p = prevailing_odr_type (p);
+ gcc_checking_assert (TYPE_MAIN_VARIANT (p) == p);
+   }
+
   /* Make void * compatible with char * and also void **.
 Programs are commonly violating TBAA by this.
 
Index: ipa-devirt.c
===
--- ipa-devirt.c(revision 271836)
+++ ipa-devirt.c(working copy)
@@ -2170,6 +2170,20 @@ get_odr_type (tree type, bool insert)
   return val;
 }
 
+/* Return type that in ODR type hash prevailed TYPE.  Be careful and punt
+   on ODR violations.  */
+
+tree
+prevailin

Re: [PATCH] include MEM_REF type in tree dumps (PR 90676)

2019-06-01 Thread Martin Sebor

A patch with a ChangeLog this time is attached.

On 6/1/19 9:53 AM, Martin Sebor wrote:

I spent a bunch of time the other day trying to understand why
the second of the two assignments below to a char array was
apparently not being done by trunk

   a[0] = 1;
   a[1] = 0;

The optimized GIMPLE dump simply shows:

   MEM[(char *)&a] = 1;

when in the past it showed:

   MEM[(char[2] *)&a2] = 1;

After some debugging I figured out that this is the result of
the store merging pass transforming the two assignments into
one:

   *(short int *)a = 1;

and the MEM_REF dump mentioning only the type of the second
operand and not the type of the access.

To avoid this confusion the attached patch adds to the dump
a cast to the MEM_REF type for accesses whose size is not equal
to the size of the operand (when the sizes are the same no new
cast is prepended).  The effect is that with store merging in
effect, the dump for the above becomes

   MEM[(short int *)(char *)&a] = 1;

This should make both the size and the type of the access clear
and help avoid the confusion.  The output isn't the same as in
earlier releases because because the access really is done via
a short pointer and not as an array of char.

There is more detail in MEM_REF that could be included here but
it seems that the size of the access is essential to interpreting
the dumps.

Tested on x86_64-linux with only minimal testsuite fallout.

Martin


PR middle-end/90676 - default GIMPLE dumps lack information

gcc/ChangeLog:

	PR middle-end/90676
	* tree-pretty-print.c (dump_generic_node): Include MEM_REF type
	in output when different size than operand.

gcc/testsuite/ChangeLog:

	PR middle-end/90676
	* gcc.dg/tree-ssa/dump-6.c: New test.
	* g++.dg/tree-ssa/pr19807.C: Adjust expected output.
	* g++.dg/tree-ssa/ssa-dse-1.C: Same.
	* gcc.dg/tree-ssa/pr30375.c: Same.
	* gcc.dg/tree-ssa/slsr-27.c (f): Same.
	* gcc.dg/tree-ssa/slsr-28.c (f): Same.
	* gcc.dg/tree-ssa/slsr-29.c (f): Same.
	* gcc.dg/tree-ssa/ssa-dse-24.c: Same.

diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
index cbe06b4ce62..08e0dd13115 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
@@ -11,7 +11,8 @@ void foo(void)
 	z = 1 + &a[1];
 }
 
-/* { dg-final { scan-tree-dump-times "&MEM\\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "&MEM\\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" { target { ! store_merge } } } }
+   { dg-final { scan-tree-dump-times "&MEM\\\[\\(int \\*\\)\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" { target { store_merge } } } } */
 
 
 void bar(int i)
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
index 1fd8dec99e9..da9fc3b9c6a 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
@@ -97,5 +97,5 @@ int main()
 }
 
 
-/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct FixBuf \\*\\)& \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */
-
+/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct FixBuf \\*\\)& \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { ! store_merge } } } }
+   { dg-final { scan-tree-dump-times "MEM\\\[\\(char\\\[176] \\*\\)\\(struct FixBuf \\*\\)& \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { store_merge } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dump-6.c b/gcc/testsuite/gcc.dg/tree-ssa/dump-6.c
new file mode 100644
index 000..8b4a51c6cbf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/dump-6.c
@@ -0,0 +1,37 @@
+/* PR middle-end/90676 - default GIMPLE dumps lack information
+   { dg-do compile }
+   { dg-options "-O2 -fdump-tree-store-merging" }
+   { dg-require-effective-target int32plus }
+   { dg-require-effective-target store_merge } */
+
+
+extern char a2[2];
+
+void f2 (void)
+{
+  a2[0] = 1;
+  a2[1] = 0;
+}
+
+extern char a4[4];
+
+void f4 (void)
+{
+  a4[0] = 1;
+  a4[1] = 0;
+  a4[2] = 0;
+  a4[3] = 0;
+}
+
+extern char a8[8];
+
+void f8 (void)
+{
+  a8[0] = 1;
+  for (int i = 1; i != 8; ++i)
+a8[i] = 0;
+}
+
+/* { dg-final { scan-tree-dump "MEM\\\[\\(unsigned short \\*\\)\\(char \\*\\)\\&a2] = " "store-merging"} }
+   { dg-final { scan-tree-dump "MEM\\\[\\(unsigned int \\*\\)\\(char \\*\\)\\&a4] = " "store-merging"} }
+   { dg-final { scan-tree-dump "MEM\\\[\\(unsigned long \\*\\)\\(char \\*\\)\\&a8] = " "store-merging"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c b/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
index 4494a2b0bd6..1d47e4c39eb 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
@@ -22,5 +22,6 @@ void test_signed_msg_encoding(void)
 f();
 }
 
-/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct _s \\*\\)&signInfo \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */
+/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct _s \\*\\)&signInfo \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { ! store_merge } } } }
+   { dg-final { scan-tree-du

[3/3] Fix debug info for LSM

2019-06-01 Thread Richard Sandiford
This patch makes the into-SSA code handle LSM temporary variables
as though they had been assignments to the original variable.

In the end, the easiest place to record the link seemed to be
DECL_ABSTRACT_ORIGIN.  These sorts of nameless temporaries shouldn't
otherwise have debug info and so shouldn't be using DECL_ABSTRACT_ORIGIN
for anything else.


2019-06-01  Richard Sandiford  

gcc/
* gimple.h (gimple_assign_load_decl_p): New function.
* tree-ssa.h (inherit_target_for_debug_bind): Declare.
* tree-ssa.c (inherit_target_for_debug_bind): New function.
(target_for_debug_bind): Honor calls to inherit_target_for_debug_bind.
* tree-into-ssa.c (maybe_register_def): Don't emit "VAR => DEF"
for "DEF = VAR".
* tree-ssa-loop-im.c: Include tree-ssa.h.
(execute_sm_if_changed): Explain why we don't insert any debug
statements here.
(execute_sm): Call inherit_target_for_debug_bind on the temporary
variable.

gcc/testsuite/
* lib/gcc-gdb-test.exp (gdb-test): Add a syntax for specifying
the Nth hit of a breakpoint.
* gcc.dg/guality/loop-2.c: New test.
* gcc.dg/guality/loop-3.c: Likewise.
* gcc.dg/guality/loop-4.c: Likewise.

Index: gcc/gimple.h
===
--- gcc/gimple.h2019-06-01 16:52:38.0 +0100
+++ gcc/gimple.h2019-06-01 16:52:39.075271587 +0100
@@ -2782,6 +2782,18 @@ gimple_assign_load_p (const gimple *gs)
 }
 
 
+/* Return true if GS is an assignment that loads DECL into its lhs.  */
+
+static inline bool
+gimple_assign_load_decl_p (const gimple *gs, tree decl)
+{
+  const gassign *assign = dyn_cast  (gs);
+  return (assign
+ && gimple_assign_single_p (assign)
+ && get_base_address (gimple_assign_rhs1 (assign)) == decl);
+}
+
+
 /* Return true if S is a type-cast assignment.  */
 
 static inline bool
Index: gcc/tree-ssa.h
===
--- gcc/tree-ssa.h  2019-06-01 16:52:38.0 +0100
+++ gcc/tree-ssa.h  2019-06-01 16:52:39.079271578 +0100
@@ -39,6 +39,7 @@ extern void redirect_edge_var_map_empty
 extern edge ssa_redirect_edge (edge, basic_block);
 extern void flush_pending_stmts (edge);
 extern void gimple_replace_ssa_lhs (gimple *, tree);
+extern void inherit_target_for_debug_bind (tree, tree);
 extern tree target_for_debug_bind (tree);
 extern void insert_debug_temp_for_var_def (gimple_stmt_iterator *, tree);
 extern void insert_debug_temps_for_defs (gimple_stmt_iterator *);
Index: gcc/tree-ssa.c
===
--- gcc/tree-ssa.c  2019-06-01 16:52:38.0 +0100
+++ gcc/tree-ssa.c  2019-06-01 16:52:39.079271578 +0100
@@ -232,6 +232,25 @@ gimple_replace_ssa_lhs (gimple *stmt, tr
   gimple_set_lhs (stmt, nlhs);
 }
 
+/* Record that assignments to new temporary variable VAR should be treated
+   for debug purposes like an assignment to ORIGIN.  More specifically,
+   record that the value of target_for_debug_bind (VAR) should track the
+   value of target_for_debug_bind (ORIGIN).
+
+   This can be useful when replacing all references to ORIGIN with VAR
+   in a particular region of code.  */
+
+void
+inherit_target_for_debug_bind (tree var, tree origin)
+{
+  gcc_assert (VAR_P (var)
+ && DECL_IGNORED_P (var)
+ && DECL_ARTIFICIAL (var)
+ && DECL_NAMELESS (var)
+ && !DECL_ABSTRACT_ORIGIN (var));
+  if (target_for_debug_bind (origin))
+DECL_ABSTRACT_ORIGIN (var) = origin;
+}
 
 /* Given a tree for an expression for which we might want to emit
locations or values in debug information (generally a variable, but
@@ -252,6 +271,12 @@ target_for_debug_bind (tree var)
return NULL_TREE;
 }
 
+  /* Honor choices made through inherit_target_for_debug_bind.  */
+  if (VAR_P (var)
+  && DECL_IGNORED_P (var)
+  && !DECL_IGNORED_P (DECL_ORIGIN (var)))
+var = DECL_ORIGIN (var);
+
   if ((!VAR_P (var) || VAR_DECL_IS_VIRTUAL_OPERAND (var))
   && TREE_CODE (var) != PARM_DECL)
 return NULL_TREE;
Index: gcc/tree-into-ssa.c
===
--- gcc/tree-into-ssa.c 2019-06-01 16:52:38.0 +0100
+++ gcc/tree-into-ssa.c 2019-06-01 16:52:39.079271578 +0100
@@ -1916,7 +1916,12 @@ maybe_register_def (def_operand_p def_p,
  SET_DEF (def_p, def);
 
  tree tracked_var = target_for_debug_bind (sym);
- if (tracked_var)
+ /* Don't emit "VAR => DEF" for "DEF = VAR".  Although not
+semantically wrong, it leads to more resets when the load
+from VAR is (or might become) partly speculative.  */
+ if (tracked_var
+ && !(track_direct_refs_for_debug_p (tracked_var)
+  && gimple_assign_load_decl_p (stmt, tracked_var)))
{
  gimple *note = gimple_bu

[PATCH] include MEM_REF type in tree dumps (PR 90676)

2019-06-01 Thread Martin Sebor

I spent a bunch of time the other day trying to understand why
the second of the two assignments below to a char array was
apparently not being done by trunk

  a[0] = 1;
  a[1] = 0;

The optimized GIMPLE dump simply shows:

  MEM[(char *)&a] = 1;

when in the past it showed:

  MEM[(char[2] *)&a2] = 1;

After some debugging I figured out that this is the result of
the store merging pass transforming the two assignments into
one:

  *(short int *)a = 1;

and the MEM_REF dump mentioning only the type of the second
operand and not the type of the access.

To avoid this confusion the attached patch adds to the dump
a cast to the MEM_REF type for accesses whose size is not equal
to the size of the operand (when the sizes are the same no new
cast is prepended).  The effect is that with store merging in
effect, the dump for the above becomes

  MEM[(short int *)(char *)&a] = 1;

This should make both the size and the type of the access clear
and help avoid the confusion.  The output isn't the same as in
earlier releases because because the access really is done via
a short pointer and not as an array of char.

There is more detail in MEM_REF that could be included here but
it seems that the size of the access is essential to interpreting
the dumps.

Tested on x86_64-linux with only minimal testsuite fallout.

Martin
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
index cbe06b4ce62..08e0dd13115 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
@@ -11,7 +11,8 @@ void foo(void)
 	z = 1 + &a[1];
 }
 
-/* { dg-final { scan-tree-dump-times "&MEM\\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "&MEM\\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" { target { ! store_merge } } } }
+   { dg-final { scan-tree-dump-times "&MEM\\\[\\(int \\*\\)\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" { target { store_merge } } } } */
 
 
 void bar(int i)
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
index 1fd8dec99e9..da9fc3b9c6a 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-1.C
@@ -97,5 +97,5 @@ int main()
 }
 
 
-/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct FixBuf \\*\\)& \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */
-
+/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct FixBuf \\*\\)& \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { ! store_merge } } } }
+   { dg-final { scan-tree-dump-times "MEM\\\[\\(char\\\[176] \\*\\)\\(struct FixBuf \\*\\)& \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { store_merge } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dump-6.c b/gcc/testsuite/gcc.dg/tree-ssa/dump-6.c
new file mode 100644
index 000..8b4a51c6cbf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/dump-6.c
@@ -0,0 +1,37 @@
+/* PR middle-end/90676 - default GIMPLE dumps lack information
+   { dg-do compile }
+   { dg-options "-O2 -fdump-tree-store-merging" }
+   { dg-require-effective-target int32plus }
+   { dg-require-effective-target store_merge } */
+
+
+extern char a2[2];
+
+void f2 (void)
+{
+  a2[0] = 1;
+  a2[1] = 0;
+}
+
+extern char a4[4];
+
+void f4 (void)
+{
+  a4[0] = 1;
+  a4[1] = 0;
+  a4[2] = 0;
+  a4[3] = 0;
+}
+
+extern char a8[8];
+
+void f8 (void)
+{
+  a8[0] = 1;
+  for (int i = 1; i != 8; ++i)
+a8[i] = 0;
+}
+
+/* { dg-final { scan-tree-dump "MEM\\\[\\(unsigned short \\*\\)\\(char \\*\\)\\&a2] = " "store-merging"} }
+   { dg-final { scan-tree-dump "MEM\\\[\\(unsigned int \\*\\)\\(char \\*\\)\\&a4] = " "store-merging"} }
+   { dg-final { scan-tree-dump "MEM\\\[\\(unsigned long \\*\\)\\(char \\*\\)\\&a8] = " "store-merging"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c b/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
index 4494a2b0bd6..1d47e4c39eb 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
@@ -22,5 +22,6 @@ void test_signed_msg_encoding(void)
 f();
 }
 
-/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct _s \\*\\)&signInfo \\+ \[0-9\]+B\\\] = {}" 1 "dse1" } } */
+/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct _s \\*\\)&signInfo \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { ! store_merge } } } }
+   { dg-final { scan-tree-dump-times "MEM\\\[\\(char\\\[8] \\*\\)\\(struct _s \\*\\)&signInfo \\+ \[0-9\]+B\\\] = {}" 1 "dse1" { target { store_merge } } } } */
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c
index 35b3d00ee44..ea9aad9c4cc 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c
@@ -19,4 +19,5 @@ f (struct x *p, unsigned int n)
 /* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom3" { target { int32 } } } } */
 /* { dg-final { scan-tree-dump-times "\\* 2;" 1 "dom3" { target { int16 } } } } */
 /* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+;" 1 "dom3" } } */
-/* { dg-

[2/3] Track debug locations of some memory variables

2019-06-01 Thread Richard Sandiford
This patch tries to track the debug location of memory variables
that have a target_for_debug_bind (and thus have a type that
satisfies is_gimple_reg_type).  For each such variable V:

* "# DEBUG V s=> V" marks the start of V's lifetime

* during V's lifetime, "# DEBUG V => X" records that the value of V is
  given by X instead of DECL_RTL (V).

* each assignment to V implicitly reestablishes the link between V
  and DECL_RTL (V).

* as before, "V = {CLOBBER}" marks the end of V's lifetime.

When removing "V = X", gsi_remove tries to insert the equivalent of
"# DEBUG V => X" at the place of the original assignment, falling back
on a "# DEBUG V => NULL" reset if that fails.

The change to insert_debug_temp_for_var_def is mostly reindentation.

The patch only handles VAR_DECLs, but we might want to extend it
to PARM_DECLs too.


2019-06-01  Richard Sandiford  

gcc/
* tree-core.h (tree_decl_with_vis): Group bitfields into bytes.
(tree_decl_with_vis::track_direct_refs_for_debug_p): New field.
* tree-streamer-in.c (unpack_ts_decl_with_vis_value_fields): Handle it.
* tree-streamer-out.c (pack_ts_decl_with_vis_value_fields): Likewise.
* tree.h (DECL_TRACK_DIRECT_REFS_FOR_DEBUG_P): New macro.
(track_direct_refs_for_debug_p): New function.
* cfgexpand.c (expand_debug_locations): Use DECL_RTL_REF to
handle VAR s=> VAR.
(expand_gimple_basic_block): Insert the initialized equivalent
of VAR s=> VAR after each direct assignment to VAR.
* gimplify.c (scoped_possible_mem_var_p): New function, split out
from...
(gimplify_bind_expr): ...here.  Decide whether it would be worth
tracking the location of a non-gimple-reg VAR_DECL using debug
stmts and insns.  Mark them with DECL_TRACK_DIRECT_REFS_FOR_DEBUG_P
if so and use gimple_debug_source_binds to mark the start of their
lifetime.
* gimple-low.c (lower_stmt): Allow gimple_debug_source_binds
before lowering.
* tree-cfg.c (make_blocks): Handle gimple_debug_source_binds.
* tree-ssa.c (insert_debug_temp_for_var_def): Handle VAR_DECLs
as well as SSA_NAMEs.
(insert_debug_temps_for_defs): Insert gimple_debug_binds for
VAR_DECLs for which DECL_TRACK_DIRECT_REFS_FOR_DEBUG_P is set.

gcc/testsuite/
* gcc.dg/guality/addr-taken-1.c: New test.
* gcc.dg/guality/addr-taken-2.c: Likewise.

Index: gcc/tree-core.h
===
--- gcc/tree-core.h 2019-05-29 10:49:39.896700883 +0100
+++ gcc/tree-core.h 2019-06-01 16:38:35.421667415 +0100
@@ -1761,13 +1761,12 @@ struct GTY(()) tree_decl_with_vis {
  unsigned dllimport_flag : 1;
  /* Don't belong to VAR_DECL exclusively.  */
  unsigned weak_flag : 1;
-
  unsigned seen_in_bind_expr : 1;
+
  unsigned comdat_flag : 1;
  /* Used for FUNCTION_DECL, VAR_DECL and in C++ for TYPE_DECL.  */
  ENUM_BITFIELD(symbol_visibility) visibility : 2;
  unsigned visibility_specified : 1;
-
  /* Belong to FUNCTION_DECL exclusively.  */
  unsigned init_priority_p : 1;
  /* Used by C++ only.  Might become a generic decl flag.  */
@@ -1776,11 +1775,16 @@ struct GTY(()) tree_decl_with_vis {
  unsigned cxx_constructor : 1;
  /* Belong to FUNCTION_DECL exclusively.  */
  unsigned cxx_destructor : 1;
+
  /* Belong to FUNCTION_DECL exclusively.  */
  unsigned final : 1;
  /* Belong to FUNCTION_DECL exclusively.  */
  unsigned regdecl_flag : 1;
- /* 14 unused bits. */
+ /* Records whether direct references to VAR_DECLs should be tracked via
+debug stmts.  */
+ unsigned track_direct_refs_for_debug_p : 1;
+
+ /* 13 unused bits. */
 };
 
 struct GTY(()) tree_var_decl {
Index: gcc/tree-streamer-in.c
===
--- gcc/tree-streamer-in.c  2019-05-29 10:49:39.896700883 +0100
+++ gcc/tree-streamer-in.c  2019-06-01 16:38:35.421667415 +0100
@@ -307,6 +307,8 @@ unpack_ts_decl_with_vis_value_fields (st
 {
   DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1);
   DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1);
+  DECL_TRACK_DIRECT_REFS_FOR_DEBUG_P (expr)
+   = (unsigned) bp_unpack_value (bp, 1);
 }
 
   if (TREE_CODE (expr) == FUNCTION_DECL)
Index: gcc/tree-streamer-out.c
===
--- gcc/tree-streamer-out.c 2019-05-29 10:49:39.620701683 +0100
+++ gcc/tree-streamer-out.c 2019-06-01 16:38:35.421667415 +0100
@@ -269,6 +269,7 @@ pack_ts_decl_with_vis_value_fields (stru
   bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
   /* DECL_IN_TEXT_SECTION is set during final asm output only. */
   bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
+  bp_pack_value (bp, DECL_TRACK_DIRECT_REFS_FOR_DEBUG_P (expr), 1);
 }
 
   if (TREE_CODE (expr) == FUNCTION_DECL)
Index: gcc/tree.h
===

[1/3] Add a DECL_RTL_REF rtx code

2019-06-01 Thread Richard Sandiford
This patch adds a new rtx code for capturing a decl's DECL_RTL by
reference rather than by value.  When used in a VAR_LOCATION, the
VAR_LOCATION continues to track the decl as it changes over time,
rather than "remembering" the value that the decl had at the point
of the VAR_LOCATION.

2019-06-01  Richard Sandiford  

gcc/
* rtl.def (DEF_RTL_EXPR): New rtx code.
* doc/rtl.texi: Document it.
* rtl.h (DECL_RTL_REF_TARGET): New macro.
* rtl.c (rtx_equal_p_cb, rtx_equal_p): Handle DEF_RTL_EXPR.
* alias.c (rtx_equal_for_memref_p): Likewise.
* cselib.c (invariant_or_equiv_p, rtx_equal_for_cselib_1)
(cselib_hash_rtx): Likewise.
* dwarf2out.c (mem_loc_descriptor): Likewise.
* print-rtl.c (rtx_writer::print_rtx_operand): Likewise.

Index: gcc/rtl.def
===
--- gcc/rtl.def 2019-05-31 17:27:35.155089238 +0100
+++ gcc/rtl.def 2019-06-01 16:38:31.985677188 +0100
@@ -775,6 +775,11 @@ DEF_RTL_EXPR(DEBUG_IMPLICIT_PTR, "debug_
parameter.  */
 DEF_RTL_EXPR(ENTRY_VALUE, "entry_value", "0", RTX_OBJ)
 
+/* Captures the DECL_RTL of a DECL by reference rather than by value,
+   so that it tracks the DECL_RTL as it evolves over time.  The single
+   argument is the DECL, accessed via DECL_RTL_REF_TARGET.  */
+DEF_RTL_EXPR(DECL_RTL_REF, "decl_rtl_ref", "t", RTX_OBJ)
+
 /* Used in VAR_LOCATION for a reference to a parameter that has
been optimized away completely.  */
 DEF_RTL_EXPR(DEBUG_PARAMETER_REF, "debug_parameter_ref", "t", RTX_OBJ)
Index: gcc/doc/rtl.texi
===
--- gcc/doc/rtl.texi2019-03-08 18:14:25.581010702 +
+++ gcc/doc/rtl.texi2019-06-01 16:38:31.969677234 +0100
@@ -3675,6 +3675,14 @@ Stands for the location of a @var{decl}
 Stands for the value a @var{decl} had at the entry point of the
 containing function.
 
+@findex decl_rtl_ref
+@item (decl_rtl_ref:@var{mode} @var{decl})
+Captures @samp{DECL_RTL (@var{decl})} by reference rather than by value,
+so that it tracks the @code{DECL_RTL} as it evolves over time.  This is
+useful for describing the debug location of a variable that spends part
+of its lifetime in memory and that can be indirectly modified while
+stored in memory.
+
 @findex debug_parameter_ref
 @item (debug_parameter_ref:@var{mode} @var{decl})
 Refers to a parameter that was completely optimized out.
@@ -4018,11 +4026,20 @@ temporaries and determining expressions
 value of each user variable at as many points (ranges, actually) in the
 program as possible.
 
-Unlike @code{NOTE_INSN_VAR_LOCATION}, the value expression in an
-@code{INSN_VAR_LOCATION} denotes a value at that specific point in the
-program, rather than an expression that can be evaluated at any later
-point before an overriding @code{VAR_LOCATION} is encountered.  E.g.,
-if a user variable is bound to a @code{REG} and then a subsequent insn
+@findex decl_rtl_ref
+@code{INSN_VAR_LOCATION} and @code{NOTE_INSN_VAR_LOCATION} differ in the
+way that they ``capture'' potentially-variable parts of an expression.
+An @code{INSN_VAR_LOCATION} captures any potentially-variable subexpression
+@emph{by value} unless it contains an explicit by-reference capture
+such as @code{decl_rtl_ref}.  A @code{NOTE_INSN_VAR_LOCATION}
+instead captures @emph{every} subexpression by reference.
+
+Capturing a subexpression @var{x} by value means that the subexpression
+represents the value @var{x} had at that particular point in time.
+Capturing by reference means that the subexpression tracks the value
+of @var{x} as it evolves over time.
+
+E.g., if a user variable is bound to a @code{REG} and then a subsequent insn
 modifies the @code{REG}, the note location would keep mapping the user
 variable to the register across the insn, whereas the insn location
 would keep the variable bound to the value, so that the variable
Index: gcc/rtl.h
===
--- gcc/rtl.h   2019-05-29 10:49:39.892700893 +0100
+++ gcc/rtl.h   2019-06-01 16:38:31.985677188 +0100
@@ -1608,6 +1608,9 @@ #define REG_NOTES(INSN)   XEXP(INSN, 6)
question.  */
 #define ENTRY_VALUE_EXP(RTX) (RTL_CHECKC1 (RTX, 0, ENTRY_VALUE).rt_rtx)
 
+/* The decl referenced by a DECL_RTL_REF.  */
+#define DECL_RTL_REF_TARGET(RTX) (RTL_CHECKC1 (RTX, 0, DECL_RTL_REF).rt_tree)
+
 enum reg_note
 {
 #define DEF_REG_NOTE(NAME) NAME,
Index: gcc/rtl.c
===
--- gcc/rtl.c   2019-04-26 10:59:07.730195479 +0100
+++ gcc/rtl.c   2019-06-01 16:38:31.985677188 +0100
@@ -486,6 +486,9 @@ rtx_equal_p_cb (const_rtx x, const_rtx y
 case ENTRY_VALUE:
   return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
 
+case DECL_RTL_REF:
+  return DECL_RTL_REF_TARGET (x) == DECL_RTL_REF_TARGET (y);
+
 default:
   break;
 }
@@ -628,6 +631,9 @@ rtx_equal_p (const_rtx x, const_r

[0/3] Improve debug info for addressable vars

2019-06-01 Thread Richard Sandiford
Taking the address of a variable stops us doing var-tracking on it,
so that we just use the DECL_RTL instead.  This can easily cause wrong
debug info for regions of code that would have had correct debug info
if the variable weren't addressable.  E.g.:

{
  int base;
  get_start (&base);
  x[i1] = base;
  base += 1; // No need to store this
  x[i2] = base; // ...so the debug info for "base" is wrong here
}

or (the motivating example):

{
  int base;
  get_start (&base);
  for (int i = 0; i < n; ++i)
{
  x[i] = base;
  base += y[i]; // Can apply LSM here, so the debug info for "base"
// in the loop is wrong
}
  consume (&base);
}

This patch series lets us use the DECL_RTL location for some parts of a
variable's lifetime and debug-bind locations for other parts:

1) Gimple uses "VAR s=> VAR" to bind VAR to its DECL_RTL.  The binding
   holds until overridden.

2) RTL does the same thing using:

 (var_location VAR (decl_rtl_ref VAR))

   where DECL_RTL_REF is a new rtx code that captures the DECL_RTL
   by reference rather than by value.

   We can't just use "(var_location VAR (mem X))" for this, because
   that would bind VAR to the value that (mem X) has at that exact point.
   VAR would therefore get reset by any possible change to (mem X),
   whereas here we want it to track (possibly indirect) updates instead.

3) The gimplifier decides which variables should get the new treatment
   and emits "VAR s=> VAR" to mark the start of VAR's lifetime.
   Clobbers continue to mark the end of VAR's lifetime.

4) Stores to VAR implicitly reestablish the link between VAR and its
   DECL_RTL.  This is simpler (and IMO more robust) than inserting an
   explicit "VAR s=> VAR" at every write.

5) gsi_remove tries to insert "VAR => X" in place of a deleted "VAR = X",
   falling back to a "VAR => NULL" reset if that fails.

Patch 1 handles the new rtl code, patch 2 adds the gimple framework,
and patch 3 uses it for LSM.

Bootstrapped & regtested on aarch64-linux-gnu and x86_64-linux-gnu.
OK to install?

Richard


Re: Simplify loop size when step=1

2019-06-01 Thread Jeff Law
On 6/1/19 2:41 AM, Marc Glisse wrote:
> Hello,
> 
> this is a small short-cut in the common case where the step is 1. This
> avoids having ldist generate a BIT_AND_EXPR that requires VRP to remove,
> then forwprop to clean up, etc, very close to the end of the
> optimization pipeline. Please do check that the test s==1 is the right one.
> 
> An alternative would be to add a match.pd transformation
> 
> (simplify
>  (bit_and (exact_div@3 @0 INTEGER_CST@1) INTEGER_CST@2)
>  (if (...)
>   @3))
> 
> but that duplicates VRP functionality, so I don't like it much, I'd
> rather compute the range of new SSA_NAMEs when we create them.
> 
> Bootstrap+regtest on x86_64-pc-linux-gnu.
> 
> 2019-06-03  Marc Glisse  
> 
> * tree-ssa-loop-niter.c (number_of_iterations_ne): Skip
> computations when step is 1.
> 
OK
jeff


[PATCH] Move rust_{is_mangled,demangle_sym} to a private libiberty header.

2019-06-01 Thread Eduard-Mihai Burtescu
When libiberty/rust-demangle.c was initially added, its two exports,
rust_is_mangled and rust_demangle_sym, made it to include/demangle.h.
However, these two functions are merely implementation details of
cplus_demangle and rust_demangle, only the latter should be public.

This is becoming a problem, because the new Rust mangling scheme
does not fit this "postprocess after C++ demangling" API at all,
so rust_demangle_sym would forever be stuck supporting only the
legacy mangling, whereas rust_demangle can easily handle both
(the new version of which I plan to upstream soon).

I'm hoping that libiberty doesn't have strict backwards-compat
requirements, so that we can hide these two functions.
Also, as far as I'm aware, nobody is using them in the wild.

2019-06-01  Eduard-Mihai Burtescu  
include/ChangeLog:
* demangle.h (rust_is_mangled): Move to libiberty/rust-demangle.h.
(rust_demangle_sym): Move to libiberty/rust-demangle.h.
libiberty/ChangeLog:
* cplus-dem.c: Include rust-demangle.h.
* rust-demangle.c: Include rust-demangle.h.
* rust-demangle.h: New file.

diff --git a/include/demangle.h b/include/demangle.h
index f5d9b9e8b..06c32571d 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -159,24 +159,6 @@ ada_demangle (const char *mangled, int options);
 extern char *
 dlang_demangle (const char *mangled, int options);
 
-/* Returns non-zero iff MANGLED is a rust mangled symbol.  MANGLED must
-   already have been demangled through cplus_demangle_v3.  If this function
-   returns non-zero then MANGLED can be demangled (in-place) using
-   RUST_DEMANGLE_SYM.  */
-extern int
-rust_is_mangled (const char *mangled);
-
-/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
-   If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
-   replace characters that cannot be demangled with '?' and might truncate
-   SYM.  After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
-   larger.  */
-extern void
-rust_demangle_sym (char *sym);
-
-/* Demangles MANGLED if it was GNU_V3 and then RUST mangled, otherwise
-   returns NULL. Uses CPLUS_DEMANGLE_V3, RUST_IS_MANGLED and
-   RUST_DEMANGLE_SYM.  Returns a new string that is owned by the caller.  */
 extern char *
 rust_demangle (const char *mangled, int options);
 
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index afceed2a1..a39e2bf2e 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -52,6 +52,7 @@ void * realloc ();
 #define CURRENT_DEMANGLING_STYLE options
 
 #include "libiberty.h"
+#include "rust-demangle.h"
 
 enum demangling_styles current_demangling_style = auto_demangling;
 
diff --git a/libiberty/rust-demangle.c b/libiberty/rust-demangle.c
index 9b2d2dbe6..2302db45b 100644
--- a/libiberty/rust-demangle.c
+++ b/libiberty/rust-demangle.c
@@ -47,6 +47,7 @@ extern void *memset(void *s, int c, size_t n);
 
 #include 
 #include "libiberty.h"
+#include "rust-demangle.h"
 
 
 /* Mangled Rust symbols look like this:
diff --git a/libiberty/rust-demangle.h b/libiberty/rust-demangle.h
new file mode 100644
index 0..abf4c6cde
--- /dev/null
+++ b/libiberty/rust-demangle.h
@@ -0,0 +1,45 @@
+/* Internal demangler interface for the Rust programming language.
+   Copyright (C) 2016-2019 Free Software Foundation, Inc.
+   Written by David Tolnay (dtol...@gmail.com).
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU Library General Public
+License, the Free Software Foundation gives you unlimited permission
+to link the compiled version of this file into combinations with other
+programs, and to distribute those combinations without any restriction
+coming from the use of this file.  (The Library Public License
+restrictions do apply in other respects; for example, they cover
+modification of the file, and distribution when not linked into a
+combined executable.)
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.
+If not, see .  */
+
+/* This file provides some definitions shared by cplus-dem.c and
+   rust-demangle.c.  It should not be included by any other files.  */
+
+/* Returns non-zero iff MANGLED is a rust mangled symbol.  MANGLED must
+   already have been demangled through cplus_demangle_v3.  If this function
+   returns non-zero then MANGLED can be demangled (in-place) using
+   RUST_DEMANGLE_SYM.  */
+extern int
+

Re: [PATCH] Clean up non-conforming names

2019-06-01 Thread Jonathan Wakely

On 31/05/19 17:15 -0700, Thomas Rodgers wrote:


Revising previous version of this patch to pick another missed
uglification.


OK for trunk, thanks.

I also see this one:

include/pstl/parallel_backend_tbb.h:__buffer(std::size_t n) : 
_M_allocator(), _M_ptr(_M_allocator.allocate(n)), _M_buf_size(n) {}





Odd behaviour of indirect_ref_may_alias_decl_p in vn oracle

2019-06-01 Thread Jan Hubicka
Hi,
while looking for the reason for extra disambiguations in
aliasing_component_refs I have noticed an odd case.  We newly disambiguate:

MEM[(Element_t *)_27 + 4B];

s.globalIDDataBase_m;

 
unit-size 
align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
0x770fb5e8 precision:32 min  max 

pointer_to_this >
tree_0 tree_2
arg:0 
public unsigned DI
size 
unit-size 
align:64 warn_if_not_align:0 symtab:0 alias-set 216 canonical-type 
0x762df888>
visited
def_stmt _27 = &MEM[(struct OneDomain_t 
*)&s].D.113982.domain_m[i_26].D.110783.D.44395;
version:27
ptr-info 0x75c66540>
arg:1  
constant 4>>
 
unit-size 
align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
0x7494b7e0 fields  context 

full-name "class GlobalIDDataBase"
needs-constructor needs-destructor X() X(constX&) this=(X&) 
n_parents=0 use_template=0 interface-unknown
pointer_to_this  reference_to_this 
 chain >
sizes-gimplified public unsigned type_6 DI
size 
unit-size 
align:64 warn_if_not_align:0 symtab:0 alias-set 484 canonical-type 
0x7494bf18
pointer_to_this >
   
arg:0 
unit-size 
align:64 warn_if_not_align:0 symtab:0 alias-set 604 canonical-type 
0x7294d888 fields  context 

full-name "class INode<3>"
needs-constructor needs-destructor X() X(constX&) this=(X&) 
n_parents=0 use_template=1 interface-unknown
pointer_to_this  reference_to_this 
 chain >
tree_1 tree_2
arg:0 
arg:0 >
arg:1 >
arg:1 
used private unsigned nonlocal decl_3 DI 
/aux/hubicka/tramp3d-v4b.cpp:5583:21 size  
unit-size 
align:64 warn_if_not_align:0 offset_align 128
offset  bit-offset  context 
chain 
used private nonlocal decl_3 SI /aux/hubicka/tramp3d-v4b.cpp:5584:13
size 
unit-size 
align:32 warn_if_not_align:0 offset_align 128
offset 
bit-offset  context 
 chain >>
/aux/hubicka/tramp3d-v4b.cpp:5457:24 start: 
/aux/hubicka/tramp3d-v4b.cpp:5457:24 finish: 
/aux/hubicka/tramp3d-v4b.cpp:5457:24>

that did not make sense to me becaue ref1 type is integer_type and ref2 is
pointer_type so these should be disambiguated by usual TBAA querry earlier.

What happens is the following.  The analysis happens via vn_reference_lookup
which does
  if (! tbaa_p)
r.ref_alias_set = r.base_alias_set = 0;
later this is passed as ref1 but because it reffers to decl the order is
exchanged so it appears as ref2 in in indirect_ref_may_alias_decl_p.
Now there is test:
  /* If the alias set for a pointer access is zero all bets are off.  */   
  if (base1_alias_set == 0)
return true;   
which is ok, since base1_alias_set is non-0 (it is coming from indirect_ref).

I think the code is not supposed to work this way :)

I not convinced we realy want to give up on TBAA when ref is actual
decl?  At least polymorphic call analysis is using the assumption that
placement news do not happen here.

This patch fixes the odd case in conservative way and also reduces
number of disambiguations noticeably:

from
  aliasing_component_ref_p: 636 disambiguations, 15844 queries
to
  aliasing_component_ref_p: 136 disambiguations, 13943 queries

Can we construct valid placement new testcase where this matters?

Honza

* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Also give up
TBAA path when base2_alias_set is 0.
Index: tree-ssa-alias.c
===
--- tree-ssa-alias.c(revision 271813)
+++ tree-ssa-alias.c(working copy)
@@ -1295,7 +1296,7 @@ indirect_ref_may_alias_decl_p (tree ref1
   ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1));
 
   /* If the alias set for a pointer access is zero all bets are off.  */
-  if (base1_alias_set == 0)
+  if (base1_alias_set == 0 || base2_alias_set == 0)
 return true;
 
   /* When we are trying to disambiguate an access with a pointer dereference


Simplify loop size when step=1

2019-06-01 Thread Marc Glisse

Hello,

this is a small short-cut in the common case where the step is 1. This 
avoids having ldist generate a BIT_AND_EXPR that requires VRP to remove, 
then forwprop to clean up, etc, very close to the end of the optimization 
pipeline. Please do check that the test s==1 is the right one.


An alternative would be to add a match.pd transformation

(simplify
 (bit_and (exact_div@3 @0 INTEGER_CST@1) INTEGER_CST@2)
 (if (...)
  @3))

but that duplicates VRP functionality, so I don't like it much, I'd rather 
compute the range of new SSA_NAMEs when we create them.


Bootstrap+regtest on x86_64-pc-linux-gnu.

2019-06-03  Marc Glisse  

* tree-ssa-loop-niter.c (number_of_iterations_ne): Skip
computations when step is 1.

--
Marc GlisseIndex: gcc/tree-ssa-loop-niter.c
===
--- gcc/tree-ssa-loop-niter.c	(revision 271834)
+++ gcc/tree-ssa-loop-niter.c	(working copy)
@@ -1118,22 +1118,29 @@ number_of_iterations_ne (struct loop *lo
 	 assumptions for divisibility of c.  */
   assumption = fold_build2 (FLOOR_MOD_EXPR, niter_type, c, d);
   assumption = fold_build2 (EQ_EXPR, boolean_type_node,
 assumption, build_int_cst (niter_type, 0));
   if (!integer_nonzerop (assumption))
 	niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
 	  niter->assumptions, assumption);
 }
 
   c = fold_build2 (EXACT_DIV_EXPR, niter_type, c, d);
-  tmp = fold_build2 (MULT_EXPR, niter_type, c, inverse (s, bound));
-  niter->niter = fold_build2 (BIT_AND_EXPR, niter_type, tmp, bound);
+  if (integer_onep (s))
+{
+  niter->niter = c;
+}
+  else
+{
+  tmp = fold_build2 (MULT_EXPR, niter_type, c, inverse (s, bound));
+  niter->niter = fold_build2 (BIT_AND_EXPR, niter_type, tmp, bound);
+}
   return true;
 }
 
 /* Checks whether we can determine the final value of the control variable
of the loop with ending condition IV0 < IV1 (computed in TYPE).
DELTA is the difference IV1->base - IV0->base, STEP is the absolute value
of the step.  The assumptions necessary to ensure that the computation
of the final value does not overflow are recorded in NITER.  If we
find the final value, we adjust DELTA and return TRUE.  Otherwise
we return false.  BNDS bounds the value of IV1->base - IV0->base,