Re: [AARCH64] Add support of ARMv8.4 in saphira for Qualcomm server part

2018-05-29 Thread Sameera Deshpande
On Tue 29 May, 2018, 9:19 PM Siddhesh Poyarekar, <
siddhesh.poyare...@linaro.org> wrote:

> On 29 May 2018 at 21:17, James Greenhalgh 
> wrote:
> > On Tue, May 29, 2018 at 05:01:42AM -0500, Sameera Deshpande wrote:
> >> Hi!
> >>
> >> Please find attached the patch to add support of ARMv8.4 in saphira
> >> for Qualcomm server part. Tested on aarch64, without any regressions.
> >>
> >> Ok for trunk?
> >
> > I'm trusting that this is the right thing to do for this core. As
> Siddhesh
> > contributed the original patch; I'd like him to also sign off on this
> > modification.
> >
> > OK for trunk with Siddhesh's ack.
>
> LGTM too.
>
> Thanks,
> Siddhesh
>

Thanks James and Siddhesh.

- Sameera

>


[PATCH] relax -Wsizeof-pointer-memaccess for strncpy with size of source (PR 85931)

2018-05-29 Thread Martin Sebor

Warning for a strncpy call whose bound is the same as the size
of the source and suggesting to use the size of the source is
less than helpful when both sizes are the same, as in:

  char a[4], b[4];
  strncpy (a, b, sizeof b);

The attached patch suppresses the -Wsizeof-pointer-memaccess
warning for these cases.  To do that even for VLAs (in some
cases), the patch enhances operand_equal_p() to handle
SAVE_EXPR to detect when VLA in sizeof VLA refers to the size
of a variable-length array.

Is this okay for trunk and GCC 8?

Martin
PR c/85931 -  -Wsizeof-pointer-memaccess for strncpy with size of source

gcc/c-family/ChangeLog:

	PR c/85931
	* c-warn.c (sizeof_pointer_memaccess_warning): Avoid warning when
	sizeof source and destination yields the same value.

gcc/ChangeLog:

	PR c/85931
	* fold-const.c (operand_equal_p): Handle SAVE_EXPR.

gcc/testsuite/ChangeLog:

	PR c/85931
	* gcc.dg/Wstringop-truncation-3.c: New test.

diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index e7bcbb1..96a56d4 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -792,13 +792,31 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
 {
   /* The argument type may be an array.  Diagnose bounded string
 	 copy functions that specify the bound in terms of the source
-	 argument rather than the destination.  */
+	 argument rather than the destination unless they are equal
+	 to one another.  Handle constant sizes and also try to handle
+	 sizeof expressions involving VLAs.  */
   if (strop && !cmp && fncode != BUILT_IN_STRNDUP && src)
 	{
 	  tem = tree_strip_nop_conversions (src);
 	  if (TREE_CODE (tem) == ADDR_EXPR)
 	tem = TREE_OPERAND (tem, 0);
-	  if (operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF))
+
+	  tree d = tree_strip_nop_conversions (dest);
+	  if (TREE_CODE (d) == ADDR_EXPR)
+	d = TREE_OPERAND (d, 0);
+
+	  tree dstsz = TYPE_SIZE_UNIT (TREE_TYPE (d));
+	  tree srcsz = TYPE_SIZE_UNIT (TREE_TYPE (tem));
+
+	  if ((!dstsz
+	   || !srcsz
+	   || (TREE_CODE (dstsz) != INTEGER_CST
+		   && TREE_CODE (srcsz) != INTEGER_CST
+		   && !operand_equal_p (dstsz, srcsz, OEP_LEXICOGRAPHIC))
+	   || (TREE_CODE (dstsz) == INTEGER_CST
+		   && TREE_CODE (srcsz) == INTEGER_CST
+		   && !tree_int_cst_equal (dstsz, srcsz)))
+	  && operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF))
 	warning_at (sizeof_arg_loc[idx], OPT_Wsizeof_pointer_memaccess,
 			"argument to % in %qD call is the same "
 			"expression as the source; did you mean to use "
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3258aad..ead6e53 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3358,6 +3358,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
 
 	case CLEANUP_POINT_EXPR:
 	case EXPR_STMT:
+	case SAVE_EXPR:
 	  if (flags & OEP_LEXICOGRAPHIC)
 	return OP_SAME (0);
 	  return 0;
diff --git a/gcc/testsuite/gcc.dg/Wstringop-truncation-3.c b/gcc/testsuite/gcc.dg/Wstringop-truncation-3.c
new file mode 100644
index 000..57f4d64
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-truncation-3.c
@@ -0,0 +1,59 @@
+/* PR c/85931 - -Wsizeof-pointer-memaccess for strncpy with size of source
+   { dg-do compile }
+   { dg-options "-O2 -Wall -Wstringop-truncation -ftrack-macro-expansion=0" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern char* strncpy (char*, const char*, size_t);
+
+extern char a3[3], b3[3];
+extern char a5[5], b5[5];
+extern char ax[], bx[];
+
+struct SA
+{
+  char a3[3], b3[3];
+  char a5[5], b5[5];
+  char ax[];
+};
+
+void sink (void*, ...);
+
+#define T(d, s, n)   sink (strncpy (d, s, n))
+
+void test_array (unsigned n)
+{
+  T (a3, b3, 3);
+  /* For the following statemenmt, GCC 8.1 issues warning:
+
+   argument to ‘sizeof’ in ‘strncpy’ call is the same expression
+   as the source; did you mean to use the size of the destination?
+
+ Since the size of both the source and destination the warning
+ isn't helpful.  Verify that it isn't issued.  */
+  T (a3, b3, sizeof b3);/* { dg-bogus "\\\[-Wsizeof-pointer-memaccess" } */
+
+  T (a3, ax, sizeof a3);/* { dg-warning "\\\[-Wstringop-truncation" } */
+  T (ax, a3, sizeof a3);/* { dg-warning "argument to .sizeof. in .strncpy. call is the same expression as the source" } */
+
+  char an[n], bn[n];
+  sink (an, bn);
+
+  T (an, bn, sizeof bn);/* { dg-bogus "\\\[-Wsizeof-pointer-memaccess" } */
+}
+
+void test_member_array (struct SA *sa, unsigned n)
+{
+  T (sa->a3, sa->b3, 3);
+  T (sa->a3, sa->b3, sizeof sa->b3);  /* { dg-bogus "\\\[-Wsizeof-pointer-memaccess" } */
+
+  T (sa->a3, sa->ax, sizeof sa->a3);  /* { dg-warning "\\\[-Wstringop-truncation" } */
+  T (sa->ax, sa->a3, sizeof sa->a3);  /* { dg-warning "argument to .sizeof. in .strncpy. call is the same expression as the source" } */
+
+  struct VarLenStruct {
+char an[n], bn[n];
+  } x;
+
+  sink ();
+  T (x.an, x.bn, sizeof x.bn);/* { dg-bogus 

libgo patch committed: make vet tool work with gccgo

2018-05-29 Thread Ian Lance Taylor
Update libgo so that the vet tool works with gccgo.  This is a
backport of https://golang.org/cl/113715 and
https://golang.org/cl/113716:

cmd/go: don't pass -compiler flag to vet

Without this running go vet -compiler=gccgo causes vet to fail.
The vet tool does need to know the compiler, but it is passed in
vetConfig.Compiler.

cmd/go, cmd/vet, go/internal/gccgoimport: make vet work with gccgo

When using libgo, there is no package file for a standard library
package. Since it is impossible for the go tool to rebuild the
package, and since the package file exists only in the form of a .gox
file, this seems like the best choice. Unfortunately it was confusing
vet, which wanted to see a real file. This caused vet to report errors
about missing package files for standard library packages. The
gccgoimporter knows how to correctly handle this case. Fix this by

1) telling vet which packages are standard;
2) letting vet skip those packages;
3) letting the gccgoimporter handle this case.

As a separate required fix, libgo has no runtime/cgo package, so don't
try to depend on it (as it happens, this fixes
https://golang.org/issue/25324).

Bootstrapped and ran Go tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
Index: gcc/go/gofrontend/MERGE
===
--- gcc/go/gofrontend/MERGE (revision 260908)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -1,4 +1,4 @@
-572b19513766e9e5cc4aa8d984a89c93880726ba
+9731580e76c065b76e3a103356bb8920da05a685
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/go/cmd/go/internal/load/pkg.go
===
--- libgo/go/cmd/go/internal/load/pkg.go(revision 260097)
+++ libgo/go/cmd/go/internal/load/pkg.go(working copy)
@@ -1010,7 +1010,7 @@ func (p *Package) load(stk *ImportStack,
 
// Cgo translation adds imports of "runtime/cgo" and "syscall",
// except for certain packages, to avoid circular dependencies.
-   if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) {
+   if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && 
cfg.BuildContext.Compiler != "gccgo" {
addImport("runtime/cgo")
}
if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
@@ -1019,7 +1019,9 @@ func (p *Package) load(stk *ImportStack,
 
// SWIG adds imports of some standard packages.
if p.UsesSwig() {
-   addImport("runtime/cgo")
+   if cfg.BuildContext.Compiler != "gccgo" {
+   addImport("runtime/cgo")
+   }
addImport("syscall")
addImport("sync")
 
@@ -1225,7 +1227,7 @@ func LinkerDeps(p *Package) []string {
deps := []string{"runtime"}
 
// External linking mode forces an import of runtime/cgo.
-   if externalLinkingForced(p) {
+   if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
deps = append(deps, "runtime/cgo")
}
// On ARM with GOARM=5, it forces an import of math, for soft floating 
point.
Index: libgo/go/cmd/go/internal/vet/vetflag.go
===
--- libgo/go/cmd/go/internal/vet/vetflag.go (revision 260048)
+++ libgo/go/cmd/go/internal/vet/vetflag.go (working copy)
@@ -90,7 +90,7 @@ func vetFlags(args []string) (passToVet,
}
switch f.Name {
// Flags known to the build but not to vet, so must be 
dropped.
-   case "x", "n", "vettool":
+   case "x", "n", "vettool", "compiler":
if extraWord {
args = append(args[:i], args[i+2:]...)
extraWord = false
Index: libgo/go/cmd/go/internal/work/exec.go
===
--- libgo/go/cmd/go/internal/work/exec.go   (revision 260097)
+++ libgo/go/cmd/go/internal/work/exec.go   (working copy)
@@ -512,6 +512,7 @@ func (b *Builder) build(a *Action) (err
ImportPath:  a.Package.ImportPath,
ImportMap:   make(map[string]string),
PackageFile: make(map[string]string),
+   Standard:make(map[string]bool),
}
a.vetCfg = vcfg
for i, raw := range a.Package.Internal.RawImports {
@@ -548,17 +549,24 @@ func (b *Builder) build(a *Action) (err
 
for _, a1 := range a.Deps {
p1 := a1.Package
-   if p1 == nil || p1.ImportPath == "" || a1.built == "" {
+   if p1 == nil || p1.ImportPath == "" {
continue
}
-   fmt.Fprintf(, "packagefile 

libgo patch committed: add path to AIX certificate file

2018-05-29 Thread Ian Lance Taylor
This libgo patch by Tony Reix adds a patch to the AIX certificate
file.  Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.
Committed to mainline.

Ian
Index: gcc/go/gofrontend/MERGE
===
--- gcc/go/gofrontend/MERGE (revision 260097)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -1,4 +1,4 @@
-290c93f08f4456f0552b0764e28573164e47f259
+572b19513766e9e5cc4aa8d984a89c93880726ba
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: libgo/go/crypto/x509/root_aix.go
===
--- libgo/go/crypto/x509/root_aix.go(revision 260048)
+++ libgo/go/crypto/x509/root_aix.go(working copy)
@@ -5,4 +5,6 @@
 package x509
 
 // Possible certificate files; stop after finding one.
-var certFiles []string
+var certFiles = []string{
+   "/var/ssl/certs/ca-bundle.crt",
+}


Re: [PATCH][Middle-end][version 3]2nd patch of PR78809 and PR83026

2018-05-29 Thread Qing Zhao
Hi, Jeff,

Thanks a lot for your review and comments.

I have updated my patch based on your suggestion, and retested this whole patch 
on both X86 and aarch64.

please take a look at the patch again.

thanks.

Qing

> On May 25, 2018, at 3:38 PM, Jeff Law  wrote:

> So I originally thought you had the core logic wrong in the immediate
> uses loop.  But it's actually the case that the return value is the
> exact opposite of what I expected.
> 
> ie, I expected "TRUE" to mean the call was transformed, "FALSE" if it
> was not transformed.
> 
> Can you fix that so it's not so confusing?
> 
> I think with that change we'll be good to go, but please repost for a
> final looksie.
> 
> THanks,
> Jeff



0001-2nd-Patch-for-PR78009.patch
Description: Binary data


[PATCH] PR fortran/85981 -- Check kind of errmsg variable.

2018-05-29 Thread Steve Kargl
The new comment in the patch explains the patch.  This was
developed and tested on 8-branch, but will be applied to
trunk prior to committing to branches.  Built and regression
tested on x86_64-*-freebsd.  OK to commit?

2018-05-29  Steven G. Kargl  

PR fortran/85981
* resolve.c (resolve_allocate_deallocate): Check errmsg is default
character kind.

2018-05-29  Steven G. Kargl  

PR fortran/85981

* gfortran.dg/allocate_alloc_opt_14.f90: New test.
* gfortran.dg/allocate_alloc_opt_1.f90: Update error string.
* gfortran.dg/allocate_stat_2.f90: Ditto.
* gfortran.dg/deallocate_alloc_opt_1.f90: Ditto.

-- 
Steve
Index: gcc/fortran/resolve.c
===
--- gcc/fortran/resolve.c	(revision 260769)
+++ gcc/fortran/resolve.c	(working copy)
@@ -7763,12 +7763,17 @@ resolve_allocate_deallocate (gfc_code *code, const cha
   gfc_check_vardef_context (errmsg, false, false, false,
 _("ERRMSG variable"));
 
+  /* F18:R928  alloc-opt is ERRMSG = errmsg-variable
+	 F18:R930  errmsg-variable   is scalar-default-char-variable
+	 F18:R906  default-char-variable is variable
+	 F18:C906  default-char-variable shall be default character.  */
   if ((errmsg->ts.type != BT_CHARACTER
 	   && !(errmsg->ref
 		&& (errmsg->ref->type == REF_ARRAY
 		|| errmsg->ref->type == REF_COMPONENT)))
-	  || errmsg->rank > 0 )
-	gfc_error ("Errmsg-variable at %L must be a scalar CHARACTER "
+	  || errmsg->rank > 0
+	  || errmsg->ts.kind != gfc_default_character_kind)
+	gfc_error ("ERRMSG variable at %L shall be a scalar default CHARACTER "
 		   "variable", >where);
 
   for (p = code->ext.alloc.list; p; p = p->next)
Index: gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90
===
--- gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90	(revision 260767)
+++ gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90	(working copy)
@@ -22,7 +22,7 @@ program a
   allocate(i(2))) ! { dg-error "Syntax error in ALLOCATE" }
   allocate(i(2), errmsg=err, errmsg=err) ! { dg-error "Redundant ERRMSG" }
   allocate(i(2), errmsg=err) ! { dg-warning "useless without a STAT" }
-  allocate(i(2), stat=j, errmsg=x) ! { dg-error "must be a scalar CHARACTER" }
+  allocate(i(2), stat=j, errmsg=x) ! { dg-error "shall be a scalar default CHARACTER" }
 
   allocate(err) ! { dg-error "neither a data pointer nor an allocatable" }
 
Index: gcc/testsuite/gfortran.dg/allocate_alloc_opt_14.f90
===
--- gcc/testsuite/gfortran.dg/allocate_alloc_opt_14.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/allocate_alloc_opt_14.f90	(working copy)
@@ -0,0 +1,8 @@
+! { dg-do compile }
+program p
+   integer, allocatable :: arr(:)
+   integer :: stat
+   character(len=128, kind=4) :: errmsg = ' '
+   allocate (arr(3), stat=stat, errmsg=errmsg)  ! { dg-error "shall be a scalar default CHARACTER" }
+   print *, allocated(arr), stat, trim(errmsg)
+end
Index: gcc/testsuite/gfortran.dg/allocate_stat_2.f90
===
--- gcc/testsuite/gfortran.dg/allocate_stat_2.f90	(revision 260767)
+++ gcc/testsuite/gfortran.dg/allocate_stat_2.f90	(working copy)
@@ -5,6 +5,6 @@ program main
   character(len=30), dimension(2) :: er
   integer, dimension (:), allocatable :: a
   allocate (a (16), stat = ier) ! { dg-error "must be a scalar INTEGER" }
-  allocate (a (14), stat=ier(1),errmsg=er) ! { dg-error "must be a scalar CHARACTER" }
+  allocate (a (14), stat=ier(1),errmsg=er) ! { dg-error "shall be a scalar default CHARACTER" }
 end
 
Index: gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90
===
--- gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90	(revision 260767)
+++ gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90	(working copy)
@@ -22,7 +22,7 @@ program a
   deallocate(i)) ! { dg-error "Syntax error in DEALLOCATE" }
   deallocate(i, errmsg=err, errmsg=err) ! { dg-error "Redundant ERRMSG" }
   deallocate(i, errmsg=err) ! { dg-warning "useless without a STAT" }
-  deallocate(i, stat=j, errmsg=x) ! { dg-error "must be a scalar CHARACTER" }
+  deallocate(i, stat=j, errmsg=x) ! { dg-error "shall be a scalar default CHARACTER" }
 
   deallocate(err) ! { dg-error "nonprocedure pointer nor an allocatable" }
 


Re: [PATCH] [MSP430] Allow interrupt handers to be static and fix __interrupt__ attribute causing an ICE

2018-05-29 Thread DJ Delorie
Jozef Lawrynowicz  writes:
> If an argument is passed to the interrupt attribute, GCC will create a section
> for the interrupt vector when outputting the assembly. This, combined with the
> code to ensure the interrupt function doesn't get optimized out, ensures the
> symbol for the interrupt function is available when it comes to linking.

> I did also test on hardware that static interrupts works as expected, and they
> do.

It sounds like things have changed since I first wrote that code, so as
long as it works now, I'm OK with it :-)


Re: C++ PATCH for c++/85889, reject capturing a structured binding

2018-05-29 Thread Ville Voutilainen
On 30 May 2018 at 01:23, Jason Merrill  wrote:
> On Tue, May 29, 2018 at 4:44 PM, Marek Polacek  wrote:
>> [expr.prim.lambda.capture] p8 says "If a lambda-expression explicitly 
>> captures
>> an entity that is not odr-usable or captures a structured binding (explicitly
>> or implicitly), the program is ill-formed."
>
> That's a pretty recent change, and seems to be controversial, so I
> think let's hold off on this patch for now.

Yep, I asked the bug to be suspended, and Jonathan did so. I very much
intend to revert this
particular change in the standard, or morph it so that capturing
bindings is clearly well-formed.


Re: [PATCH] RISC-V: Add interrupt attribute support.

2018-05-29 Thread Jim Wilson
On Tue, May 29, 2018 at 7:32 AM, Nathan Sidwell  wrote:
> On 05/25/2018 06:30 PM, Jim Wilson wrote:
>
>> -/* Return true if func is a naked function.  */
>> +/* Return true if funcion TYPE is an interrupt function.  */
>
> .^^^
>>
>> +static bool
>> +riscv_interrupt_type_p (tree type)
>
>
>
> funcion?

I checked in a patch to fix the typo.

Jim
* config/riscv/riscv.c (riscv_interrupt_type): Fix comment typo.

Index: gcc/config/riscv/riscv.c
===
--- gcc/config/riscv/riscv.c(revision 260906)
+++ gcc/config/riscv/riscv.c(working copy)
@@ -2721,7 +2721,7 @@
   return NULL_TREE;
 }
 
-/* Return true if funcion TYPE is an interrupt function.  */
+/* Return true if function TYPE is an interrupt function.  */
 static bool
 riscv_interrupt_type_p (tree type)
 {


Re: C++ PATCH for c++/85889, reject capturing a structured binding

2018-05-29 Thread Jason Merrill
On Tue, May 29, 2018 at 4:44 PM, Marek Polacek  wrote:
> [expr.prim.lambda.capture] p8 says "If a lambda-expression explicitly captures
> an entity that is not odr-usable or captures a structured binding (explicitly
> or implicitly), the program is ill-formed."

That's a pretty recent change, and seems to be controversial, so I
think let's hold off on this patch for now.

Jason


Re: [PATCH] [MSP430] Allow interrupt handers to be static and fix __interrupt__ attribute causing an ICE

2018-05-29 Thread Jozef Lawrynowicz

On 29/05/18 19:45, DJ Delorie wrote:

The reason I required interrupt handlers to be non-static is because the
linker builds the interrupt handler table using weak references.  If the
handler is static, it won't be added to the table, and never called.

So you'd need a test to ensure that the handler was properly entered
into the table as well.


If an argument is passed to the interrupt attribute, GCC will create a section
for the interrupt vector when outputting the assembly. This, combined with the
code to ensure the interrupt function doesn't get optimized out, ensures the
symbol for the interrupt function is available when it comes to linking.

KEEP directives in the linker script for the interrupt vector sections will
prevent the interrupt function from getting optimized out in the final
executable, even with -Os and --gc-sections.

The only difference between a static interrupt and a regular interrupt
function in the linked executable is that the symbol for the interrupt
function name is global for the regular interrupt, but local for the static
interrupt. However, in both cases the address for the interrupt function name
is successfully added to the handler table.

So I believe that as long as the tests scanning the assembly output for the
interrupt vector section name pass, the interrupt function address will be
loaded into the vector table, provided the user has correctly used KEEP
directives in the linker script.

It doesn't really seem possible (as far as I'm aware), to coerce the GCC
testsuite into checking the address of the function loaded into the vector
table matches the address of the function in the text section, in a linked
executable. I could perhaps add something along these lines to the msp430 ld
testsuite in binutils if you think it's necessary.

I did also test on hardware that static interrupts works as expected, and they
do.

Thanks,
Jozef




C++ PATCH for c++/85889, reject capturing a structured binding

2018-05-29 Thread Marek Polacek
[expr.prim.lambda.capture] p8 says "If a lambda-expression explicitly captures
an entity that is not odr-usable or captures a structured binding (explicitly
or implicitly), the program is ill-formed."
but we weren't respecting that and the attached testcase compiled.  I think we
can reject such uses in add_capture.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-05-29  Marek Polacek  

PR c++/85889
* lambda.c (add_capture): Give error when capturing a structured
binding.

* g++.dg/cpp1z/decomp16.C: New test.
* g++.dg/cpp1z/decomp46.C: New test.

diff --git gcc/cp/lambda.c gcc/cp/lambda.c
index 9c1b49b4d8e..c3d0decba08 100644
--- gcc/cp/lambda.c
+++ gcc/cp/lambda.c
@@ -569,6 +569,12 @@ add_capture (tree lambda, tree id, tree orig_init, bool 
by_reference_p,
   if (type == error_mark_node)
return error_mark_node;
 
+  if (DECL_DECOMPOSITION_P (initializer))
+   {
+ error ("cannot capture a structured binding %qE", initializer);
+ return error_mark_node;
+   }
+
   if (id == this_identifier && !by_reference_p)
{
  gcc_assert (INDIRECT_TYPE_P (type));
diff --git gcc/testsuite/g++.dg/cpp1z/decomp16.C 
gcc/testsuite/g++.dg/cpp1z/decomp16.C
index dad69b89c08..89ed774d614 100644
--- gcc/testsuite/g++.dg/cpp1z/decomp16.C
+++ gcc/testsuite/g++.dg/cpp1z/decomp16.C
@@ -8,7 +8,7 @@ void
 foo ()
 {
   auto [ a, b ] = A ();
-  for (; auto [ a, b ] = A (); )   // { dg-error 
"expected|no match" }
+  for (; auto [ a, b ] = A (); )   // { dg-error 
"expected|no match|cannot" }
 ;
   for (; false; auto [ a, b ] = A ())  // { dg-error 
"expected" }
 ;
diff --git gcc/testsuite/g++.dg/cpp1z/decomp46.C 
gcc/testsuite/g++.dg/cpp1z/decomp46.C
index e69de29bb2d..cf5c8be6368 100644
--- gcc/testsuite/g++.dg/cpp1z/decomp46.C
+++ gcc/testsuite/g++.dg/cpp1z/decomp46.C
@@ -0,0 +1,26 @@
+// PR c++/85889
+// { dg-do compile }
+// { dg-options "-std=c++17" }
+
+struct X { int i, j; };
+void
+f ()
+{
+  X x{};
+  auto [i, j] = x;
+
+  auto [m, n] = X ();
+
+  [i]() { }; // { dg-error "cannot capture a structured binding" }
+  []() { }; // { dg-error "cannot capture a structured binding" }
+  [j]() { }; // { dg-error "cannot capture a structured binding" }
+  []() { }; // { dg-error "cannot capture a structured binding" }
+  [=]() { return i; }; // { dg-error "cannot capture a structured binding" }
+  [&]() { return i; }; // { dg-error "cannot capture a structured binding" }
+  [=]() { return j; }; // { dg-error "cannot capture a structured binding" }
+  [&]() { return j; }; // { dg-error "cannot capture a structured binding" }
+  [&, i]() { return i; }; // { dg-error "cannot capture a structured binding" }
+  [=, ]() { return i; }; // { dg-error "cannot capture a structured binding" 
}
+  [&, i]() { return j; }; // { dg-error "cannot capture a structured binding" }
+  [=, ]() { return j; }; // { dg-error "cannot capture a structured binding" 
}
+}


Re: [C++ PATCH] Do not warn about zero-as-null when NULL is used.

2018-05-29 Thread Ville Voutilainen
Another round. The other occurrence of maybe_warn_zero_as_null_pointer_constant
in typeck.c seems superfluous. The one in cvt.c seems necessary for
cpp0x/Wzero-as-null* tests. It seems like cp_build_binary_op is far more suited
to check the EQ_EXPR/NE_EXPR cases than conversion_null_warnings is.

Tested manually on Linux-x64, running full suite on Linux-PPC64. Ok for trunk?

2018-05-29  Ville Voutilainen  

gcc/cp/

Do not warn about zero-as-null when NULL is used.
* typeck.c (cp_build_binary_op): Diagnose zero as null here..
* call.c (conversion_null_warnings): ..and here..
* cvt.c (cp_convert_to_pointer): ..not here.

testsuite/

Do not warn about zero-as-null when NULL is used.
* g++.dg/warn/Wzero-as-null-pointer-constant-7.C: New.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7aadd64..5890b73 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6517,6 +6517,7 @@ build_temp (tree expr, tree type, int flags,
 }
 
 /* Perform warnings about peculiar, but valid, conversions from/to NULL.
+   Also handle a subset of zero as null warnings.
EXPR is implicitly converted to type TOTYPE.
FN and ARGNUM are used for diagnostics.  */
 
@@ -6551,6 +6552,17 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
 	warning_at (input_location, OPT_Wconversion_null,
 		"converting % to pointer type %qT", totype);
 }
+  /* Handle zero as null pointer warnings for cases other
+ than EQ_EXPR and NE_EXPR */
+  else if (!null_node_p (expr))
+{
+  source_location loc =
+	expansion_point_location_if_in_system_header (input_location);
+  if (null_ptr_cst_p (expr)
+	  && (TYPE_PTRMEMFUNC_P (totype) || TYPE_PTRDATAMEM_P (totype)
+	  || TYPE_PTR_P (totype)))
+	maybe_warn_zero_as_null_pointer_constant (expr, loc);
+}
 }
 
 /* We gave a diagnostic during a conversion.  If this was in the second
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index f29dacd..e2f8579 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -208,9 +208,6 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold,
 	return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
  /*c_cast_p=*/false, complain);
 
-  if (complain & tf_warning)
-	maybe_warn_zero_as_null_pointer_constant (expr, loc);
-
   /* A NULL pointer-to-data-member is represented by -1, not by
 	 zero.  */
   tree val = (TYPE_PTRDATAMEM_P (type)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 3df043e..2eb4cf1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4353,6 +4353,21 @@ cp_build_binary_op (location_t location,
   warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
 }
 
+  /* Handle zero as null pointer warnings for pointer comparisons */
+  if (code == EQ_EXPR || code == NE_EXPR)
+{
+  source_location loc =
+	expansion_point_location_if_in_system_header (input_location);
+  if ((TYPE_PTRMEMFUNC_P (type0) || TYPE_PTRDATAMEM_P (type0)
+	   || TYPE_PTR_P (type0))
+	  && !null_node_p (op1) && null_ptr_cst_p (op1))
+	  maybe_warn_zero_as_null_pointer_constant (op1, loc);
+  else if ((TYPE_PTRMEMFUNC_P (type1) || TYPE_PTRDATAMEM_P (type1)
+	   || TYPE_PTR_P (type1))
+	  && !null_node_p (op0) && null_ptr_cst_p (op0))
+	maybe_warn_zero_as_null_pointer_constant (op0, loc);
+}
+
   /* In case when one of the operands of the binary operation is
  a vector and another is a scalar -- convert scalar to vector.  */
   if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE))
@@ -4833,9 +4848,6 @@ cp_build_binary_op (location_t location,
    integer_one_node,
    complain);
 
-	  if (complain & tf_warning)
-		maybe_warn_zero_as_null_pointer_constant (op1, input_location);
-
 	  e2 = cp_build_binary_op (location,
    EQ_EXPR, e2, integer_zero_node,
    complain);
diff --git a/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-7.C b/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-7.C
new file mode 100644
index 000..0d06dbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-7.C
@@ -0,0 +1,13 @@
+// { dg-options "-Wzero-as-null-pointer-constant" }
+// { dg-do compile { target c++11 } }
+
+#include 
+
+void test01()
+{
+  char* x(NULL);
+  char* x2{NULL};
+  char* x3 = NULL;
+  char* x4(0); // { dg-warning "zero as null pointer" }
+  char* x5 = 0; // { dg-warning "zero as null pointer" }
+}


Re: [PATCH] add udivhi3, umodhi3 functions to libgcc

2018-05-29 Thread Paul Koning



> On May 29, 2018, at 4:17 PM, Jakub Jelinek  wrote:
> 
> On Tue, May 29, 2018 at 03:01:20PM -0400, Paul Koning wrote:
>> +short udivmodhi4 ();
> 
> We do want real prototypes, not K declarations.

Fixed.  I had copied that from the SImode file.
> 
>> Added: svn:eol-style
>> ## -0,0 +1 ##
>> +native
> 
> Why?

My svn is set up to do that automatically, but I see GCC doesn't use this.  
Fixed.

I noticed the types in the udiv and umod functions are signed, that's also that 
way in udivmod.c.  Should I change those to unsigned?

paul

Index: config/pdp11/t-pdp11
===
--- config/pdp11/t-pdp11(revision 260806)
+++ config/pdp11/t-pdp11(working copy)
@@ -1,5 +1,7 @@
 LIB2ADD = $(srcdir)/udivmod.c \
  $(srcdir)/udivmodsi4.c \
+ $(srcdir)/udivhi3.c \
+ $(srcdir)/udivmodhi4.c \
  $(srcdir)/memcmp.c \
  $(srcdir)/memcpy.c \
  $(srcdir)/memmove.c \
Index: udivhi3.c
===
--- udivhi3.c   (nonexistent)
+++ udivhi3.c   (working copy)
@@ -0,0 +1,37 @@
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
+
+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
+.  */
+
+unsigned short udivmodhi4(unsigned short, unsigned short, int);
+
+short
+__udivhi3 (short a, short b)
+{
+  return udivmodhi4 (a, b, 0);
+}
+
+short
+__umodhi3 (short a, short b)
+{
+  return udivmodhi4 (a, b, 1);
+}
+
Index: udivmodhi4.c
===
--- udivmodhi4.c(nonexistent)
+++ udivmodhi4.c(working copy)
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
+
+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
+.  */
+
+unsigned short
+udivmodhi4(unsigned short num, unsigned short den, int modwanted)
+{
+  unsigned short bit = 1;
+  unsigned short res = 0;
+
+  while (den < num && bit && !(den & (1<<15)))
+{
+  den <<=1;
+  bit <<=1;
+}
+  while (bit)
+{
+  if (num >= den)
+   {
+ num -= den;
+ res |= bit;
+   }
+  bit >>=1;
+  den >>=1;
+}
+  if (modwanted) return num;
+  return res;
+}




[PATCH 03/10] Add optinfo, remarks and optimization records

2018-05-29 Thread David Malcolm
This patch adds a way to create optimization information or "optinfo"
instances, referring to source code locations (based on statements,
loops, or basic blocks), populate them with messages and data
(trees, statements, symtab nodes),
and to send them to up to three "sinks"/destinations:
* via -fopt-info to files/dumpfiles/stderr
* as diagnostic "remarks"
* as JSON files via -fsave-optimization-record

It doesn't add any uses of the code (except via a test plugin), so
to get a better idea of how it might work, see the later patches
in the kit (e.g. patch 5, which uses it for vectorization).

gcc/ChangeLog:
* Makefile.in (OBJS): Add optinfo.o, optinfo-emit-diagnostics.o,
optinfo-emit-fopt-info.o, optinfo-emit-json.o.
(GTFILES): Add $(srcdir)/optinfo.h.
* common.opt (fremarks): New option.
(fsave-optimization-record): New option.
* coretypes.h (struct kv_pair): Move here from dumpfile.c.
* diagnostic-color.c (color_dict): Add "remark", as bold green.
* diagnostic-core.h (remark): New decl.
* diagnostic.c (diagnostic_action_after_output): Handle DK_REMARK.
(remark): New function.
* diagnostic.def (DK_REMARK): New diagnostic kind.
* doc/invoke.texi (Remarks): New section.
(-fsave-optimization-record): New option.
(-fremarks): New option.
* dumpfile.c (struct kv_pair): Move from here to coretypes.h.
(optgroup_options): Make non-static.
(dump_loc): Make static; add overload taking no FILE *.
* dumpfile.h (dump_loc): New decl.
(optgroup_options): New decl.

gcc/fortran/ChangeLog:
* gfc-diagnostic.def (DK_REMARK): New diagnostic kind.

gcc/ChangeLog:
* gengtype.c (open_base_files): Add "optinfo.h".
* opt-functions.awk (function): Handle "Remark" by adding
CL_REMARK.
* optinfo-emit-diagnostics.cc: New file.
* optinfo-emit-diagnostics.h: New file.
* optinfo-emit-fopt-info.cc: New file.
* optinfo-emit-fopt-info.h: New file.
* optinfo-emit-json.cc: New file.
* optinfo-emit-json.h: New file.
* optinfo-internal.h: New file.
* optinfo.cc: New file.
* optinfo.h: New file.
* opts.c (print_specific_help): Handle CL_REMARK.
(common_handle_option): Likewise.
* opts.h (CL_REMARK): New macro.
(CL_MAX_OPTION_CLASS): Update for CL_REMARK.
(CL_JOINED, CL_SEPARATE, CL_UNDOCUMENTED, CL_NO_DWARF_RECORD,
CL_PCH_IGNORE): Likewise.
* profile-count.c (profile_quality_as_string): New function.
* profile-count.h (profile_quality_as_string): New decl.
(profile_count::quality): New accessor.

gcc/testsuite/ChangeLog:
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add
remarks_plugin.c.
* gcc.dg/plugin/remarks-1.c: New test.
* gcc.dg/plugin/remarks_plugin.c: New test plugin.
* lib/gcc-dg.exp (dg-remark): New function.

gcc/ChangeLog:
* toplev.c: Include "optinfo-emit-json.h".
(compile_file): Call optimization_records_start and
optimization_records_finish.
* tree-ssa-live.c: Include "optinfo.h".
(remove_unused_scope_block_p): Retain inlining information if
optinfo_wants_inlining_info_p returns true.
---
 gcc/Makefile.in  |   5 +
 gcc/common.opt   |   9 +
 gcc/coretypes.h  |   8 +
 gcc/diagnostic-color.c   |   2 +
 gcc/diagnostic-core.h|   2 +
 gcc/diagnostic.c |  17 ++
 gcc/diagnostic.def   |   1 +
 gcc/doc/invoke.texi  |  34 ++-
 gcc/dumpfile.c   |  24 +-
 gcc/dumpfile.h   |   3 +
 gcc/fortran/gfc-diagnostic.def   |   1 +
 gcc/gengtype.c   |   3 +-
 gcc/opt-functions.awk|   1 +
 gcc/optinfo-emit-diagnostics.cc  | 141 +
 gcc/optinfo-emit-diagnostics.h   |  26 ++
 gcc/optinfo-emit-fopt-info.cc| 100 +++
 gcc/optinfo-emit-fopt-info.h |  26 ++
 gcc/optinfo-emit-json.cc | 408 +++
 gcc/optinfo-emit-json.h  |  37 +++
 gcc/optinfo-internal.h   | 139 +
 gcc/optinfo.cc   | 272 ++
 gcc/optinfo.h| 389 +
 gcc/opts.c   |   4 +
 gcc/opts.h   |  13 +-
 gcc/profile-count.c  |  28 ++
 gcc/profile-count.h  |   5 +
 gcc/testsuite/gcc.dg/plugin/plugin.exp   |   2 +
 gcc/testsuite/gcc.dg/plugin/remarks-1.c  |  32 +++
 gcc/testsuite/gcc.dg/plugin/remarks_plugin.c | 

[PATCH 10/10] Experiment with optinfo in tree-ssa-loop-im.c

2018-05-29 Thread David Malcolm
---
 gcc/tree-ssa-loop-im.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 030aac0..fcf5d24 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-fold.h"
 #include "tree-scalar-evolution.h"
 #include "tree-ssa-loop-niter.h"
+#include "optinfo.h"
 
 /* TODO:  Support for predicated code motion.  I.e.
 
@@ -1125,6 +1126,12 @@ move_computations_worker (basic_block bb)
  fprintf (dump_file, "(cost %u) out of loop %d.\n\n",
   cost, level->num);
}
+  /* FIXME.  */
+  if (optinfo_enabled_p ())
+   OPTINFO_SUCCESS (stmt)
+ << "moving PHI node "
+ << stmt
+ << optinfo_printf (" (cost %u) out of loop %d", cost, level->num);
 
   if (gimple_phi_num_args (stmt) == 1)
{
@@ -1194,6 +1201,12 @@ move_computations_worker (basic_block bb)
  fprintf (dump_file, "(cost %u) out of loop %d.\n\n",
   cost, level->num);
}
+  /* FIXME.  */
+  if (optinfo_enabled_p ())
+   OPTINFO_SUCCESS (stmt)
+ << "moving statement "
+ << stmt
+ << optinfo_printf (" (cost %u) out of loop %d", cost, level->num);
 
   e = loop_preheader_edge (level);
   gcc_assert (!gimple_vdef (stmt));
-- 
1.8.5.3



[PATCH 08/10] Experiment with using optinfo for devirtualization

2018-05-29 Thread David Malcolm
gcc/ChangeLog:
* gimple-fold.c: Include "optinfo.h".
(fold_gimple_assign): Port to optinfo.
(gimple_fold_call): Likewise.
* ipa-devirt.c: Include "optinfo.h".
(ipa_devirt): Port to optinfo.
* ipa.c: Include "optinfo.h".
(walk_polymorphic_call_targets): Port to optinfo.
---
 gcc/gimple-fold.c | 29 ++---
 gcc/ipa-devirt.c  | 14 +++---
 gcc/ipa.c | 17 +++--
 3 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index bd8c44a..d8a7a8b 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -66,6 +66,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "calls.h"
 #include "tree-vector-builder.h"
 #include "tree-ssa-strlen.h"
+#include "optinfo.h"
 
 /* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
@@ -346,15 +347,14 @@ fold_gimple_assign (gimple_stmt_iterator *si)
  = possible_polymorphic_call_targets (rhs, stmt, );
if (final && targets.length () <= 1 && dbg_cnt (devirt))
  {
-   if (dump_enabled_p ())
+   if (optinfo_enabled_p ())
  {
-   location_t loc = gimple_location_safe (stmt);
-   dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
-"resolving virtual function address "
-"reference to function %s\n",
-targets.length () == 1
-? targets[0]->name ()
-: "NULL");
+   OPTINFO_SUCCESS (stmt)
+ << optinfo_printf ("resolving virtual function 
address "
+"reference to function %s",
+targets.length () == 1
+? targets[0]->name ()
+: "NULL");
  }
if (targets.length () == 1)
  {
@@ -4064,14 +4064,13 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool 
inplace)
  if (final && targets.length () <= 1 && dbg_cnt (devirt))
{
  tree lhs = gimple_call_lhs (stmt);
- if (dump_enabled_p ())
+ if (optinfo_enabled_p ())
{
- location_t loc = gimple_location_safe (stmt);
- dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
-  "folding virtual function call to %s\n",
-  targets.length () == 1
-  ? targets[0]->name ()
-  : "__builtin_unreachable");
+ OPTINFO_SUCCESS (stmt)
+   << optinfo_printf ("folding virtual function call to %s",
+  targets.length () == 1
+  ? targets[0]->name ()
+  : "__builtin_unreachable");
}
  if (targets.length () == 1)
{
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 308b6e6..f2a0785 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -131,6 +131,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "optinfo.h"
 
 /* Hash based set of pairs of types.  */
 struct type_pair
@@ -3753,14 +3754,13 @@ ipa_devirt (void)
  }
else if (dbg_cnt (devirt))
  {
-   if (dump_enabled_p ())
+   if (optinfo_enabled_p ())
   {
-location_t locus = gimple_location_safe (e->call_stmt);
-dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
-"speculatively devirtualizing call "
-"in %s to %s\n",
-n->dump_name (),
-likely_target->dump_name ());
+   OPTINFO_SUCCESS (e->call_stmt)
+ << "speculatively devirtualizing call in "
+ << n
+ << " to "
+ << likely_target;
   }
if (!likely_target->can_be_discarded_p ())
  {
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 9330de5..8daa768 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "debug.h"
 #include "stringpool.h"
 #include "attribs.h"
+#include "optinfo.h"
 
 /* Return true when NODE has ADDR reference.  */
 
@@ -222,17 +223,13 @@ walk_polymorphic_call_targets (hash_set 

[PATCH 07/10] Experiment with using optinfo for loop-handling

2018-05-29 Thread David Malcolm
gcc/ChangeLog:
* tree-ssa-loop-ivcanon.c: Include "optinfo.h".
(try_unroll_loop_completely): Port to optinfo.
(canonicalize_loop_induction_variables): Use OPTINFO_NOTE.
* tree-ssa-loop-niter.c: Include "optinfo.h".
(number_of_iterations_exit): Port to OPTINFO_FAILURE.
---
 gcc/tree-ssa-loop-ivcanon.c | 38 --
 gcc/tree-ssa-loop-niter.c   |  7 ---
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 24bf60e..0ab9d61 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "tree-cfgcleanup.h"
 #include "builtins.h"
+#include "optinfo.h"
 
 /* Specifies types of loops that may be unrolled.  */
 
@@ -936,21 +937,19 @@ try_unroll_loop_completely (struct loop *loop,
   loops_to_unloop.safe_push (loop);
   loops_to_unloop_nunroll.safe_push (n_unroll);
 
-  if (dump_enabled_p ())
+  if (optinfo_enabled_p ())
 {
   if (!n_unroll)
-dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
- "loop turned into non-loop; it never loops\n");
+   OPTINFO_SUCCESS_DETAILS (loop)
+ << "loop turned into non-loop; it never loops";
   else
 {
-  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
-   "loop with %d iterations completely unrolled",
-  (int) n_unroll);
+ pending_optinfo info = OPTINFO_SUCCESS_DETAILS (loop)
+   << optinfo_printf ("loop with %d iterations completely unrolled",
+  (int) n_unroll);
   if (loop->header->count.initialized_p ())
-dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS,
- " (header execution count %d)",
- (int)loop->header->count.to_gcov_type ());
-  dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, "\n");
+info << optinfo_printf (" (header execution count %d)",
+   (int)loop->header->count.to_gcov_type ());
 }
 }
 
@@ -1240,6 +1239,25 @@ canonicalize_loop_induction_variables (struct loop *loop,
   fprintf (dump_file, "Loop %d likely iterates at most %i times.\n",
   loop->num, (int)likely_max_loop_iterations_int (loop));
 }
+  /* FIXME: this duplicates the above usage of "dump_file".  */
+  if (optinfo_enabled_p ())
+{
+  if (TREE_CODE (niter) == INTEGER_CST)
+   OPTINFO_NOTE (loop)
+ << optinfo_printf ("loop %d iterates ", loop->num)
+ << slim (niter)
+ << " times";
+  else if (maxiter >= 0)
+   OPTINFO_NOTE (loop)
+ << optinfo_printf ("loop %d iterates at most %i times",
+loop->num,
+(int)maxiter);
+  else if (likely_max_loop_iterations_int (loop) >= 0)
+   OPTINFO_NOTE (loop)
+ << optinfo_printf ("loop %d likely iterates at most %i times",
+loop->num,
+(int)likely_max_loop_iterations_int (loop));
+}
 
   /* Remove exits that are known to be never taken based on loop bound.
  Needs to be called after compilation of max_loop_iterations_int that
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 7a54c5f..8eee6de 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-scalar-evolution.h"
 #include "params.h"
 #include "tree-dfa.h"
+#include "optinfo.h"
 
 
 /* The maximum number of dominator BBs we search for conditions
@@ -2447,9 +2448,9 @@ number_of_iterations_exit (struct loop *loop, edge exit,
 return true;
 
   if (warn)
-dump_printf_loc (MSG_MISSED_OPTIMIZATION, gimple_location_safe (stmt),
-"missed loop optimization: niters analysis ends up "
-"with assumptions.\n");
+OPTINFO_FAILURE (stmt)
+  << ("missed loop optimization: niters analysis ends up "
+ "with assumptions");
 
   return false;
 }
-- 
1.8.5.3



[PATCH 04/10] Use indentation to show nesting for -fopt-info

2018-05-29 Thread David Malcolm
This converts e.g. from:

test.c:8:3: note: === analyzing loop ===
test.c:8:3: note: === analyze_loop_nest ===
test.c:8:3: note: === vect_analyze_loop_form ===
test.c:8:3: note: === get_loop_niters ===
test.c:8:3: note: symbolic number of iterations is (unsigned int) n_9(D)
test.c:8:3: note: not vectorized: loop contains function calls or data 
references that cannot be analyzed
test.c:8:3: note: vectorized 0 loops in function

to:

test.c:8:3: note: === analyzing loop ===
test.c:8:3: note:  === analyze_loop_nest ===
test.c:8:3: note:   === vect_analyze_loop_form ===
test.c:8:3: note:=== get_loop_niters ===
test.c:8:3: note:   symbolic number of iterations is (unsigned int) n_9(D)
test.c:8:3: note:   not vectorized: loop contains function calls or data 
references that cannot be analyzed
test.c:8:3: note: vectorized 0 loops in function

showing the nesting of the optimization analysis and where each
message is being emitted from within it (this is of more use as
the number of messages and the nesting depth increases)

gcc/ChangeLog:
* optinfo-emit-fopt-info.cc (emit_optinfo_via_fopt_info): Use
indentation to show nesting.
---
 gcc/optinfo-emit-fopt-info.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/gcc/optinfo-emit-fopt-info.cc b/gcc/optinfo-emit-fopt-info.cc
index b01a301..842681f 100644
--- a/gcc/optinfo-emit-fopt-info.cc
+++ b/gcc/optinfo-emit-fopt-info.cc
@@ -58,7 +58,13 @@ emit_optinfo_via_fopt_info (const optinfo *optinfo)
   if (optinfo->details_p ())
 flags |= TDF_DETAILS;
 
+  /* Source location and "note: ".  */
   dump_loc (flags, optinfo->get_location_t ());
+
+  /* Indentation to show scope nesting.  */
+  dump_printf (flags, "%*s", get_optinfo_scope_depth (), "");
+
+  /* The text itself.  */
   for (unsigned i = 0; i < optinfo->num_items (); i++)
 {
   const optinfo_item *item = optinfo->get_item (i);
-- 
1.8.5.3



[PATCH 09/10] Experiment with using optinfo in gimple-loop-interchange.cc

2018-05-29 Thread David Malcolm
This was an experiment to try to capture information on a
loop optimization.

gcc/ChangeLog:
* gimple-loop-interchange.cc (should_interchange_loops): Add
optinfo note when interchange gives better data locality behavior.
(tree_loop_interchange::interchange): Add OPTINFO_SCOPE.
Add optinfo for successful and unsuccessful interchanges.
(prepare_perfect_loop_nest): Add OPTINFO_SCOPE.  Add
optinfo note.
(pass_linterchange::execute): Add OPTINFO_SCOPE.
---
 gcc/gimple-loop-interchange.cc | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc
index eb35263..cd32288 100644
--- a/gcc/gimple-loop-interchange.cc
+++ b/gcc/gimple-loop-interchange.cc
@@ -1556,7 +1556,19 @@ should_interchange_loops (unsigned i_idx, unsigned o_idx,
   ratio = innermost_loops_p ? INNER_STRIDE_RATIO : OUTER_STRIDE_RATIO;
   /* Do interchange if it gives better data locality behavior.  */
   if (wi::gtu_p (iloop_strides, wi::mul (oloop_strides, ratio)))
-return true;
+{
+  if (optinfo_enabled_p ())
+   OPTINFO_NOTE ((gimple *)NULL) // FIXME
+ << "interchange gives better data locality behavior: "
+ << "iloop_strides: "
+ << decu (iloop_strides)
+ << " > (oloop_strides: "
+ << decu (oloop_strides)
+ << " * ratio: "
+ << decu (ratio)
+ << ")";
+  return true;
+}
   if (wi::gtu_p (iloop_strides, oloop_strides))
 {
   /* Or it creates more invariant memory references.  */
@@ -1578,6 +1590,8 @@ bool
 tree_loop_interchange::interchange (vec datarefs,
vec ddrs)
 {
+  OPTINFO_SCOPE ("tree_loop_interchange::interchange", m_loop_nest[0]);
+
   location_t loc = find_loop_location (m_loop_nest[0]);
   bool changed_p = false;
   /* In each iteration we try to interchange I-th loop with (I+1)-th loop.
@@ -1628,6 +1642,10 @@ tree_loop_interchange::interchange 
(vec datarefs,
fprintf (dump_file,
 "Loop_pair is interchanged\n\n",
 oloop.m_loop->num, iloop.m_loop->num);
+ if (optinfo_enabled_p ())
+   OPTINFO_SUCCESS (oloop.m_loop)
+ << optinfo_printf ("Loop_pair is 
interchanged",
+oloop.m_loop->num, iloop.m_loop->num);
 
  changed_p = true;
  interchange_loops (iloop, oloop);
@@ -1641,6 +1659,10 @@ tree_loop_interchange::interchange 
(vec datarefs,
fprintf (dump_file,
 "Loop_pair is not interchanged\n\n",
 oloop.m_loop->num, iloop.m_loop->num);
+ if (optinfo_enabled_p ())
+   OPTINFO_FAILURE (oloop.m_loop)
+ << optinfo_printf ("Loop_pair is not 
interchanged",
+oloop.m_loop->num, iloop.m_loop->num);
}
 }
   simple_dce_from_worklist (m_dce_seeds);
@@ -1648,6 +1670,9 @@ tree_loop_interchange::interchange (vec 
datarefs,
   if (changed_p)
 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
 "loops interchanged in loop nest\n");
+  if (optinfo_enabled_p ())
+OPTINFO_SUCCESS (m_loop_nest[0])
+  << "loops interchanged in loop nest";
 
   return changed_p;
 }
@@ -1971,6 +1996,8 @@ static bool
 prepare_perfect_loop_nest (struct loop *loop, vec *loop_nest,
   vec *datarefs, vec *ddrs)
 {
+  OPTINFO_SCOPE ("prepare_perfect_loop_nest", loop);
+
   struct loop *start_loop = NULL, *innermost = loop;
   struct loop *outermost = loops_for_fn (cfun)->tree_root;
 
@@ -2029,6 +2056,12 @@ prepare_perfect_loop_nest (struct loop *loop, 
vec *loop_nest,
  fprintf (dump_file,
   "\nConsider loop interchange for loop_nest<%d - %d>\n",
   start_loop->num, innermost->num);
+   if (optinfo_enabled_p ())
+ {
+   OPTINFO_NOTE (start_loop)
+ << optinfo_printf ("consider loop interchange for loop_nest<%d - 
%d>",
+start_loop->num, innermost->num);
+ }
 
if (loop != start_loop)
  prune_access_strides_not_in_loop (start_loop, innermost, *datarefs);
@@ -2061,6 +2094,7 @@ pass_linterchange::execute (function *fun)
   struct loop *loop;
   FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
 {
+  OPTINFO_SCOPE ("considering loop for interchange", loop);
   vec loop_nest = vNULL;
   vec datarefs = vNULL;
   vec ddrs = vNULL;
-- 
1.8.5.3



[PATCH 02/10] Add JSON implementation

2018-05-29 Thread David Malcolm
This patch is the JSON patch I posted last year;
it adds support to gcc for reading and writing JSON,
based on DOM-like trees of json::value instances.

This is overkill for what's needed by the rest of the
patch kit (which just needs to be able to write JSON),
but this code already existed, so I'm using it for now.

gcc/ChangeLog:
* Makefile.in (OBJS): Add json.o.
* json.cc: New file.
* json.h: New file.
* selftest-run-tests.c (selftest::run_tests): Call json_cc_tests.
* selftest.h (selftest::json_cc_tests): New decl.
---
 gcc/Makefile.in  |1 +
 gcc/json.cc  | 1914 ++
 gcc/json.h   |  214 ++
 gcc/selftest-run-tests.c |1 +
 gcc/selftest.h   |1 +
 5 files changed, 2131 insertions(+)
 create mode 100644 gcc/json.cc
 create mode 100644 gcc/json.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 20bee04..b3c7d5d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1385,6 +1385,7 @@ OBJS = \
ira-color.o \
ira-emit.o \
ira-lives.o \
+   json.o \
jump.o \
langhooks.o \
lcm.o \
diff --git a/gcc/json.cc b/gcc/json.cc
new file mode 100644
index 000..e0d5a76
--- /dev/null
+++ b/gcc/json.cc
@@ -0,0 +1,1914 @@
+/* JSON parsing
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+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.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "json.h"
+#include "pretty-print.h"
+#include "math.h"
+#include "selftest.h"
+
+using namespace json;
+
+/* class json::value.  */
+
+/* Generate a char * for this json::value tree.
+   The returned value must be freed by the caller.  */
+
+char *
+value::to_str () const
+{
+  pretty_printer pp;
+  print ();
+  return xstrdup (pp_formatted_text ());
+}
+
+/* Dump this json::value tree to OUTF.
+   No formatting is done.  There are no guarantees about the order
+   in which the key/value pairs of json::objects are printed.  */
+
+void
+value::dump (FILE *outf) const
+{
+  pretty_printer pp;
+  pp_buffer ()->stream = outf;
+  print ();
+  pp_flush ();
+}
+
+/* If this json::value is a json::object, return it,
+   otherwise return NULL.  */
+
+const object *
+value::as_object () const
+{
+  if (get_kind () != JSON_OBJECT)
+return NULL;
+  return static_cast  (this);
+}
+
+/* If this json::value is a json::array, return it,
+   otherwise return NULL.  */
+
+const array *
+value::as_array () const
+{
+  if (get_kind () != JSON_ARRAY)
+return NULL;
+  return static_cast  (this);
+}
+
+/* If this json::value is a json::number, return it,
+   otherwise return NULL.  */
+
+const number *
+value::as_number () const
+{
+  if (get_kind () != JSON_NUMBER)
+return NULL;
+  return static_cast  (this);
+}
+
+/* If this json::value is a json::string, return it,
+   otherwise return NULL.  */
+
+const string *
+value::as_string () const
+{
+  if (get_kind () != JSON_STRING)
+return NULL;
+  return static_cast  (this);
+}
+
+/* Attempt to get the value of a key/value pair from this value
+   as if THIS value were an object.
+
+   If THIS is not a json::object, return write an error message to OUT_ERR
+   (which must be freed by the caller) and return false.
+
+   Otherwise write the value ptr (possibly NULL) to OUT_VALUE and
+   return true.  */
+
+bool
+value::get_optional_value_by_key (const char *name, const value *_value,
+ char *_err) const
+{
+  const json::object *obj = as_object ();
+  if (!obj)
+{
+  out_err = xstrdup ("not an object");
+  return false;
+}
+  out_value = obj->get (name);
+  return true;
+}
+
+/* Attempt to get a string value of a key/value pair from this value
+   as if THIS value were an object.
+
+   If THIS is a json::object, and KEY is either not present, is a string,
+   or is the "null" JSON literal, then return true, and write to OUT_VALUE.
+   If a string, then the ptr is written to OUT_VALUE, otherwise NULL
+   is written to OUT_VALUE.
+
+   If THIS is not a json::object, or KEY is not a string/"null",
+   return false and write an error message to OUT_ERR
+   (which must be freed by the caller).  */
+
+bool
+value::get_optional_string_by_key (const char *name, const char *_value,
+  char *_err) const
+{
+  const json::value *v;

[PATCH 06/10] Experiments with using optinfo for inlining

2018-05-29 Thread David Malcolm
gcc/ChangeLog:
* ipa-inline.c: Include "optinfo.h".
(report_inline_failed_reason): Use OPTINFO_FAILURE.
(flatten_function): Use OPTINFO_SUCCESS.
(early_inline_small_functions): Likewise.
* tree-inline.c: Include "optinfo.h".
(expand_call_inline): Use OPTINFO_SUCCESS.
---
 gcc/ipa-inline.c  | 25 +
 gcc/tree-inline.c | 10 ++
 2 files changed, 35 insertions(+)

diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index b7f213f..3fd064a 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -120,6 +120,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
+#include "optinfo.h"
 
 typedef fibonacci_heap  edge_heap_t;
 typedef fibonacci_node  edge_heap_node_t;
@@ -250,6 +251,18 @@ report_inline_failed_reason (struct cgraph_edge *e)
  (dump_file, 2, opts_for_fn (e->caller->decl),
   opts_for_fn (e->callee->ultimate_alias_target ()->decl));
 }
+  /* FIXME: partial re-implementation in terms of optinfo.  */
+  if (optinfo_enabled_p ())
+{
+  OPTINFO_FAILURE (e->call_stmt)
+   << "not inlinable: "
+   << e->caller
+   << " -> "
+   << e->callee
+   << ": "
+   << cgraph_inline_failed_string (e->inline_failed);
+  // FIXME: etc; see the option mismatch code above
+}
 }
 
  /* Decide whether sanitizer-related attributes allow inlining. */
@@ -2167,6 +2180,12 @@ flatten_function (struct cgraph_node *node, bool early)
fprintf (dump_file, " Inlining %s into %s.\n",
 xstrdup_for_dump (callee->name ()),
 xstrdup_for_dump (e->caller->name ()));
+  if (optinfo_enabled_p ())
+   OPTINFO_SUCCESS (e->call_stmt)
+ << "inlining "
+ << callee
+ << " into "
+ << e->caller;
   orig_callee = callee;
   inline_call (e, true, NULL, NULL, false);
   if (e->callee != orig_callee)
@@ -2677,6 +2696,12 @@ early_inline_small_functions (struct cgraph_node *node)
fprintf (dump_file, " Inlining %s into %s.\n",
 xstrdup_for_dump (callee->name ()),
 xstrdup_for_dump (e->caller->name ()));
+  if (optinfo_enabled_p ())
+   OPTINFO_SUCCESS (e->call_stmt)
+ << "inlining "
+ << callee
+ << " into "
+ << e->caller;
   inline_call (e, true, NULL, NULL, false);
   inlined = true;
 }
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 5a0a252..5d3598e 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -61,6 +61,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "stringpool.h"
 #include "attribs.h"
 #include "sreal.h"
+#include "optinfo.h"
 
 /* I'm not real happy about this, but we need to handle gimple and
non-gimple trees.  */
@@ -4719,6 +4720,15 @@ expand_call_inline (basic_block bb, gimple *stmt, 
copy_body_data *id)
   id->src_node->dump (dump_file);
   id->dst_node->dump (dump_file);
 }
+  /* FIXME.  */
+  if (optinfo_enabled_p ())
+OPTINFO_SUCCESS(call_stmt)
+  << "Inlining "
+  << id->src_node
+  << " to "
+  << id->dst_node
+  << optinfo_printf (" with frequency %4.2f",
+cg_edge->sreal_frequency ().to_double ());
 
   /* This is it.  Duplicate the callee body.  Assume callee is
  pre-gimplified.  Note that we must not alter the caller
-- 
1.8.5.3



[PATCH 00/10] RFC: Prototype of compiler-assisted performance analysis

2018-05-29 Thread David Malcolm
I want to provide more "actionable" information on how GCC optimizes
code, both for us (GCC developers), and for advanced end-users.

For us, I want to make it easier to get a sense of how an optimization
can be improved (bug-fixing).
For end-users, I want to make it easier to figure out which command-line
flags to try, or how to rework their code.

In particular, given a workload (or benchmark), how does the user figure
out:
  * "what did the optimizers do to the hottest code?"
  * "what *didn't* they do, and why not?"
  * "how can I make the code faster?" (either by editing the code, or the
 gcc options)
and as GCC developers:
  * "how can we make GCC do a better job on this code?"


The current situation
=

I believe we currently have four ways of emitting information on what the
optimizers are doing:

(a) -fopt-info and its variants (e.g. "-fopt-info-all").

Consider this "-fopt-info" code (from "vect_analyze_loop_form"):

  if (dump_enabled_p ())
{
   dump_printf_loc (MSG_NOTE, vect_location,
"Symbolic number of iterations is ");
   dump_generic_expr (MSG_NOTE, TDF_DETAILS, number_of_iterations);
   dump_printf (MSG_NOTE, "\n");
}

This emits text to the destination(s) of "-fopt-info", e.g.:

   foo.c:15:3: note: Symbolic number of iterations is (unsigned int) n_9(D)

With "-fopt-info-all" this would be emitted to stderr.
If "details" or "note" was added when enabling the dumpfile
(e.g. via "-fdump-tree-all-details"), it would also be added to the
dumpfile for the current pass.

Passes are tagged as being members of zero or more optimization groups
("ipa", "loop", "inline", "omp", "vec"), and these can be used to filter
which messages are emitted.  For example, the "increase_alignment" IPA
pass is tagged with both "loop" and "vec".

(b) other messages emitted to dumpfiles.  We have numerous other messages
that are written just to the dumpfiles, and don't go through -fopt-info.
Consider e.g. this from loop-unroll.c:unroll_loop_constant_iterations:

  if (dump_file)
fprintf (dump_file,
 ";; Unrolled loop %d times, constant # of iterations %i 
insns\n",
 max_unroll, num_loop_insns (loop));

(c) IR dumps emitted to dumpfiles.  execute_one_pass and
execute_one_ipa_transform_pass have this code:

  if (dump_file)
do_per_function (execute_function_dump, pass);

which captures a textual dump of the current state of each function.

(d) dot-format dumps emitted to the ".dot" dumpfiles (via the "-graph") suffix
e.g. "-fdump-tree-all-graph".

All of these options are marked as "GCC Developer Options".

How does everyone go about investigating what GCC is doing on a given
workload or benchmark?  (FWIW in the past I've been using
  "-fdump-tree-all-graph -fdump-ipa-all-graph -fdump-rtl-all-graph"
and using a custom .dot viewer that I wrote:
  https://github.com/davidmalcolm/gcc-viewer
but it's something of an ad-hoc solution).


Problems with the current situation
===

-fopt-info:

* There's no integration with profile data: the report has a "wall of text"
  feel, where the few hot sites in the code are hidden amongst the many
  cold sites, with all of them treated as of having equal importance.

* -fopt-info emits lines of the form:

   foo.c:15:3: note: Symbolic number of iterations is (unsigned int) n_9(D)

  This is purely capturing the source location of the deepest point of the
  inlining chain: if there are multiple places where a function has been
  inlined, we'll get multiple reports, with no way to distinguish them.

* If a program attempts to parse this data, it can get source location
  plus a message, but there's no structure to the messages.  For example,
  we can't extract the source location of the expressions that are referred
  to in the messages.

* There are various places where we emit MSG_NOTES that look like sections
  and subsections, e.g.:

if (dump_enabled_p ())
 dump_printf_loc (MSG_NOTE, vect_location,
  "=== vect_analyze_data_ref_dependences ===\n");

  This appears to be intended to express the start of a hierarchical
  section within the dump, but there's nothing to express the end of
  the section, and they're current printed in a flat way, again
  contributing to a "wall of text" feel.  In my prototype I've
  experimented with capturing the nesting, and highlighting it using
  indentation.

dumpfiles:

* These are per-pass-instance, capturing every function at each pass.
  There's no easy way to see how a particular function "evolved" through
  the passes.

* Some messages are written to dumpfiles, but don't go through -fopt-info.
  Some messages are gated with:

(dump_flags & TDF_DETAILS)

  The divisions seems somewhat haphazard.

None of the messages are tagged with where they came from; tracking 

[PATCH 01/10] Convert dump and optgroup flags to enums

2018-05-29 Thread David Malcolm
The dump machinery uses "int" in a few places, for two different
sets of bitmasks.

This patch makes things more self-documenting and type-safe by using
a new pair of enums: one for the dump_flags_t and another for the
optgroup_flags.

This requires adding some overloaded bit operations to the enums
in question, which, in this patch is done for each enum .  If the basic
idea is OK, should I add a template for this?  (with some kind of
magic to express that bitmasking operations are only supported on
certain opt-in enums).

gcc/c-family/ChangeLog:
* c-pretty-print.c (c_pretty_printer::statement): Use TDF_NONE
rather than 0.

gcc/ChangeLog:
* cfg.c (debug): Use TDF_NONE rather than 0.
* cfghooks.c (debug): Likewise.
* dumpfile.c (DUMP_FILE_INFO): Likewise; also for OPTGROUP.
(struct dump_option_value_info): Convert to...
(struct kv_pair): ...this template type.
(dump_options): Convert to kv_pair; use TDF_NONE
rather than 0.
(optinfo_verbosity_options): Likewise.
(optgroup_options): Convert to kv_pair; use
OPTGROUP_NONE.
(gcc::dump_manager::dump_register): Use optgroup_flags_t rather
than int for "optgroup_flags" param.
(dump_generic_expr_loc): Use dump_flags_t rather than int for
"dump_kind" param.
(dump_finish): Use TDF_NONE rather than 0.
(gcc::dump_manager::opt_info_enable_passes): Use optgroup_flags_t
rather than int for "optgroup_flags" param.  Use TDF_NONE rather
than 0.  Update for change to option_ptr.
(opt_info_switch_p_1): Convert "optgroup_flags" param from int *
to optgroup_flags_t *.  Use TDF_NONE and OPTGROUP_NONE rather than
0.  Update for changes to optinfo_verbosity_options and
optgroup_options.
(opt_info_switch_p): Convert optgroup_flags from int to
optgroup_flags_t.
* dumpfile.h (TDF_ADDRESS, TDF_SLIM, TDF_RAW, TDF_DETAILS,
TDF_STATS, TDF_BLOCKS, TDF_VOPS, TDF_LINENO, TDF_UID)
TDF_STMTADDR, TDF_GRAPH, TDF_MEMSYMS, TDF_RHS_ONLY, TDF_ASMNAME,
TDF_EH, TDF_NOUID, TDF_ALIAS, TDF_ENUMERATE_LOCALS, TDF_CSELIB,
TDF_SCEV, TDF_GIMPLE, TDF_FOLDING, MSG_OPTIMIZED_LOCATIONS,
MSG_MISSED_OPTIMIZATION, MSG_NOTE, MSG_ALL, TDF_COMPARE_DEBUG,
TDF_NONE): Convert from macros to...
(enum dump_flag): ...this new enum.
(dump_flags_t): Update to use enum.
(operator|, operator&, operator~, operator|=, operator&=):
Implement for dump_flags_t.
(OPTGROUP_NONE, OPTGROUP_IPA, OPTGROUP_LOOP, OPTGROUP_INLINE,
OPTGROUP_OMP, OPTGROUP_VEC, OPTGROUP_OTHER, OPTGROUP_ALL):
Convert from macros to...
(enum optgroup_flag): ...this new enum.
(optgroup_flags_t): New typedef.
(operator|, operator|=): Implement for optgroup_flags_t.
(struct dump_file_info): Convert field "alt_flags" to
dump_flags_t.  Convert field "optgroup_flags" to
optgroup_flags_t.
(dump_register): Convert param "optgroup_flags" to
optgroup_flags_t.
(opt_info_enable_passes): Likewise.
* early-remat.c (early_remat::dump_edge_list): Use TDF_NONE rather
than 0.
* gimple-pretty-print.c (debug): Likewise.
* gimple-ssa-store-merging.c (bswap_replace): Likewise.
(merged_store_group::apply_stores): Likewise.
* gimple-ssa-strength-reduction.c (insert_initializers): Likewise.
* gimple.c (verify_gimple_pp): Likewise.
* passes.c (pass_manager::register_one_dump_file): Convert
local "optgroup_flags" to optgroup_flags_t.
* print-tree.c (print_node): Use TDF_NONE rather than 0.
(debug): Likewise.
(debug_body): Likewise.
* tree-pass.h (struct pass_data): Convert field "optgroup_flags"
to optgroup_flags_t.
* tree-pretty-print.c (print_struct_decl): Use TDF_NONE rather
than 0.
* tree-ssa-math-opts.c (convert_mult_to_fma_1): Likewise.
(convert_mult_to_fma): Likewise.
* tree-ssa-reassoc.c (undistribute_ops_list): Likewise.
* tree-ssa-sccvn.c (vn_eliminate): Likewise.
* tree-vect-data-refs.c (dump_lower_bound): Convert param
"dump_kind" to dump_flags_t.
---
 gcc/c-family/c-pretty-print.c   |   2 +-
 gcc/cfg.c   |   4 +-
 gcc/cfghooks.c  |   2 +-
 gcc/dumpfile.c  |  56 -
 gcc/dumpfile.h  | 227 +++-
 gcc/early-remat.c   |   2 +-
 gcc/gimple-pretty-print.c   |   2 +-
 gcc/gimple-ssa-store-merging.c  |   6 +-
 gcc/gimple-ssa-strength-reduction.c |   2 +-
 gcc/gimple.c|   2 +-
 gcc/passes.c|   2 +-
 gcc/print-tree.c|   7 +-
 gcc/tree-pass.h |   2 +-
 gcc/tree-pretty-print.c |   2 

Re: [PATCH][AArch64] Fix aarch64_ira_change_pseudo_allocno_class

2018-05-29 Thread Richard Sandiford
Wilco Dijkstra  writes:
> James Greenhalgh wrote:
>
>> > Add a missing ? to aarch64_get_lane to fix a failure in the testsuite.
>>
>> > I'd prefer more detail than this for a workaround; which test, why did it
>> > start to fail, why is this the right solution, etc.
>
> It was gcc.target/aarch64/vect_copy_lane_1.c generating:
>
> test_copy_laneq_f64:
>     umov    x0, v1.d[1]
>     fmov    d0, x0
>     ret
>
> For some reason returning a double uses DImode temporaries, so it's essential
> to prefer FP_REGS here and mark the lane copy correctly.

The "?" change seems to make intrinsic sense given the extra cost of the
GPR alternative.  But I think the real reason for this failure is that
we define no V1DF patterns, and target-independent code falls back to
using moves in the corresponding *integer* mode.  So for that function
we generate the rather ugly code:

(note 6 1 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(insn 3 6 2 2 (clobber (reg/v:V1DF 92 [ aD.21157 ])) "vect_copy_lane_1.c":45 -1
 (nil))
(insn 2 3 4 2 (set (subreg:DI (reg/v:V1DF 92 [ aD.21157 ]) 0)
(reg:DI 32 v0 [ aD.21157 ])) "vect_copy_lane_1.c":45 47 {*movdi_aarch64}
 (nil))
(insn 4 2 5 2 (set (reg/v:V2DF 93 [ bD.21158 ])
(reg:V2DF 33 v1 [ bD.21158 ])) "vect_copy_lane_1.c":45 1063 
{*aarch64_simd_movv2df}
 (nil))
(note 5 4 8 2 NOTE_INSN_FUNCTION_BEG)
(insn 8 5 9 2 (set (reg:DF 95)
(vec_select:DF (reg/v:V2DF 93 [ bD.21158 ])
(parallel [
(const_int 1 [0x1])
]))) "./include/arm_neon.h":14441 1993 {aarch64_get_lanev2df}
 (nil))
(insn 9 8 11 2 (set (reg:DI 96)
(subreg:DI (reg:DF 95) 0)) "vect_copy_lane_1.c":45 47 {*movdi_aarch64}
 (nil))
(insn 11 9 10 2 (clobber (reg:V1DF 91 [  ])) "vect_copy_lane_1.c":45 -1
 (nil))
(insn 10 11 15 2 (set (subreg:DI (reg:V1DF 91 [  ]) 0)
(reg:DI 96)) "vect_copy_lane_1.c":45 47 {*movdi_aarch64}
 (nil))
(insn 15 10 16 2 (set (reg:DI 32 v0)
(subreg:DI (reg:V1DF 91 [  ]) 0)) "vect_copy_lane_1.c":45 47 
{*movdi_aarch64}
 (nil))
(insn 16 15 0 2 (use (reg/i:V1DF 32 v0)) "vect_copy_lane_1.c":45 -1
 (nil))

which by IRA gets optimised to:

(insn 9 8 15 2 (set (subreg:DF (reg:DI 96) 0)
(vec_select:DF (reg:V2DF 33 v1 [ bD.21158 ])
(parallel [
(const_int 1 [0x1])
]))) "vect_copy_lane_1.c":45 1993 {aarch64_get_lanev2df}
 (expr_list:REG_DEAD (reg:V2DF 33 v1 [ bD.21158 ])
(nil)))
(insn 15 9 16 2 (set (reg:DI 32 v0)
(reg:DI 96)) "vect_copy_lane_1.c":45 47 {*movdi_aarch64}
 (expr_list:REG_DEAD (reg:DI 96)
(nil)))
(insn 16 15 18 2 (use (reg/i:V1DF 32 v0)) "vect_copy_lane_1.c":45 -1
 (nil))

with the move now being done purely in DImode.  This defeats the
heuristic in aarch64_ira_change_pseudo_allocno_class because the
pseudo appears to be a normal integer rather than a (float) vector.

Although the "?" fixes this particular instance, I think more
complicated V1DF code would still regress by being forced to
use GENERAL_REGS.  Of course, the fix is to add the move pattern
rather than disable the heuristic...

Thanks,
Richard


Re: [PATCH] add udivhi3, umodhi3 functions to libgcc

2018-05-29 Thread Jakub Jelinek
On Tue, May 29, 2018 at 03:01:20PM -0400, Paul Koning wrote:
> +short udivmodhi4 ();

We do want real prototypes, not K declarations.

> Added: svn:eol-style
> ## -0,0 +1 ##
> +native

Why?

Jakub


C++ PATCH to add -Winit-list-lifetime (47445, 67711, 48562, 85873)

2018-05-29 Thread Jason Merrill
There have been several bug reports either being surprised that the
backing array for an initializer_list went away unexpectedly, or
asking for a warning about such situations.  This patch adds a new
warning flag -Winit-list-lifetime, on by default, to warn about

* returning an automatic initializer_list
* assignment from a temporary initializer_list
* new initializer_list
* copying the array pointer in a list constructor

Tested x86_64-pc-linux-gnu, applying to trunk.
commit eac7b107631ffa9e567a4ec1834135db2dbe8466
Author: Jason Merrill 
Date:   Wed May 23 18:32:05 2018 -0400

PR c++/67445 - returning temporary initializer_list.

PR c++/67711 - assigning from temporary initializer_list.
PR c++/48562 - new initializer_list.
* typeck.c (maybe_warn_about_returning_address_of_local): Also warn
about returning local initializer_list.
* cp-tree.h (AUTO_TEMP_NAME, TEMP_NAME_P): Remove.
* call.c (build_over_call): Warn about assignment from temporary
init_list.
* init.c (build_new_1): Warn about 'new std::initializer_list'.
(find_list_begin, maybe_warn_list_ctor): New.
(perform_member_init): Use maybe_warn_list_ctor.

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 5114543c128..6031cc356b0 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -608,6 +608,10 @@ Winit-self
 C ObjC C++ ObjC++ Var(warn_init_self) Warning LangEnabledBy(C++ ObjC++,Wall)
 Warn about variables which are initialized to themselves.
 
+Winit-list-lifetime
+C++ ObjC++ Var(warn_init_list) Warning Init(1)
+Warn about uses of std::initializer_list that can result in dangling pointers.
+
 Wimplicit
 C ObjC Var(warn_implicit) Warning LangEnabledBy(C ObjC,Wall)
 Warn about implicit declarations.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 104978ea7cd..67e404d1cb2 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8217,6 +8217,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
   tree type = TREE_TYPE (to);
   tree as_base = CLASSTYPE_AS_BASE (type);
   tree arg = argarray[1];
+  location_t loc = EXPR_LOC_OR_LOC (arg, input_location);
 
   if (is_really_empty_class (type))
 	{
@@ -8226,6 +8227,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 	}
   else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
 	{
+	  if (is_std_init_list (type)
+	  && conv_binds_ref_to_prvalue (convs[1]))
+	warning_at (loc, OPT_Winit_list_lifetime,
+			"assignment from temporary initializer_list does not "
+			"extend the lifetime of the underlying array");
 	  arg = cp_build_fold_indirect_ref (arg);
 	  val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
 	}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e18480b2805..6a97abbe4e3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5234,10 +5234,6 @@ extern GTY(()) vec *keyed_classes;
 
 #else /* NO_DOLLAR_IN_LABEL */
 
-#define AUTO_TEMP_NAME "__tmp_"
-#define TEMP_NAME_P(ID_NODE) \
-  (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, \
-	 sizeof (AUTO_TEMP_NAME) - 1))
 #define VTABLE_NAME "__vt_"
 #define VTABLE_NAME_P(ID_NODE) \
   (!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \
@@ -5272,8 +5268,6 @@ extern GTY(()) vec *keyed_classes;
   && IDENTIFIER_POINTER (ID_NODE)[2] == 't' \
   && IDENTIFIER_POINTER (ID_NODE)[3] == JOINER)
 
-#define TEMP_NAME_P(ID_NODE) \
-  (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, sizeof (AUTO_TEMP_NAME)-1))
 #define VFIELD_NAME_P(ID_NODE) \
   (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, sizeof(VFIELD_NAME)-1))
 
@@ -6888,6 +6882,7 @@ extern void finish_label_decl			(tree);
 extern cp_expr finish_parenthesized_expr	(cp_expr);
 extern tree force_paren_expr			(tree);
 extern tree maybe_undo_parenthesized_ref	(tree);
+extern tree maybe_strip_ref_conversion		(tree);
 extern tree finish_non_static_data_member   (tree, tree, tree);
 extern tree begin_stmt_expr			(void);
 extern tree finish_stmt_expr_expr		(tree, tree);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index f3beaec35cb..22a5dcddce2 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -684,6 +684,64 @@ maybe_reject_flexarray_init (tree member, tree init)
   return true;
 }
 
+/* If INIT's value can come from a call to std::initializer_list::begin,
+   return that function.  Otherwise, NULL_TREE.  */
+
+static tree
+find_list_begin (tree init)
+{
+  STRIP_NOPS (init);
+  while (TREE_CODE (init) == COMPOUND_EXPR)
+init = TREE_OPERAND (init, 1);
+  STRIP_NOPS (init);
+  if (TREE_CODE (init) == COND_EXPR)
+{
+  tree left = TREE_OPERAND (init, 1);
+  if (!left)
+	left = TREE_OPERAND (init, 0);
+  left = find_list_begin (left);
+  if (left)
+	return left;
+  return find_list_begin (TREE_OPERAND (init, 2));
+}
+  if (TREE_CODE (init) == CALL_EXPR)
+if (tree fn = get_callee_fndecl 

[PING] [PATCH] refine -Wstringop-truncation and -Wsizeof-pointer-memaccess for strncat of nonstrings (PR 85602)

2018-05-29 Thread Martin Sebor

To make review and testing easier (thank you, Franz), attached
is an updated patch rebased on top of today's trunk.

(Note that the patch intentionally doesn't suppress the warning
for the submitted test case without adding the nonstring attribute.)

On 05/25/2018 02:59 PM, Martin Sebor wrote:

Ping:
https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00869.html

On 05/17/2018 08:01 PM, Martin Sebor wrote:

The -Wstringop-truncation and -Wsizeof-pointer-memaccess warnings
I added and enhanced, respectively, in GCC 8 are arguably overly
strict for source arguments declared with the nonstring attribute.

For example, -Wsizeof-pointer-memaccess triggers for the strncat
call below:

  __attribute__ ((nonstring)) char nonstr[8];
  extern char *d;
  strncat (d, nonstr, sizeof nonstr);

even though it's still a fairly common (if unsafe) idiom from
the early UNIX days (V7 from 1979 to be exact) where strncat
was introduced.  (This use case, modulo the attribute, was
reduced from coreutils.)

Simialrly, -Wstringop-truncation warns for some strcat calls that
are actually safe, such as in:

  strcpy (nonstr, "123");
  strncat (d, nonstr, 32);

To help with the adoption of the warnings and the attribute and
avoid unnecessary churn the attached patch relaxes both warnings
to accept code like this without diagnostics.

The patch doesn't add any new warnings so I'd like it considered
for GCC 8 in addition to trunk.

Thanks
Martin




PR middle-end/85602 - -Wsizeof-pointer-memaccess for strncat with size of source

gcc/c-family/ChangeLog:

	PR middle-end/85602
	* c-warn.c (sizeof_pointer_memaccess_warning): Check for attribute
	nonstring.

gcc/ChangeLog:

	PR middle-end/85602
	* calls.c (maybe_warn_nonstring_arg): Handle strncat.
	* tree-ssa-strlen.c (is_strlen_related_p): Make extern.
	Handle integer subtraction.
	(maybe_diag_stxncpy_trunc): Handle nonstring source arguments.
	* tree-ssa-strlen.h (is_strlen_related_p): Declare.

gcc/testsuite/ChangeLog:

	PR middle-end/85602
	* c-c++-common/attr-nonstring-8.c: New test.

diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index e7bcbb1..53cd827 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gcc-rich-location.h"
 #include "gimplify.h"
 #include "c-family/c-indentation.h"
+#include "calls.h"
 
 /* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language
@@ -798,7 +799,12 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
 	  tem = tree_strip_nop_conversions (src);
 	  if (TREE_CODE (tem) == ADDR_EXPR)
 	tem = TREE_OPERAND (tem, 0);
-	  if (operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF))
+
+	  /* Avoid diagnosing sizeof SRC when SRC is declared with
+	 attribute nonstring.  */
+	  tree dummy;
+	  if (operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF)
+	  && !get_attr_nonstring_decl (tem, ))
 	warning_at (sizeof_arg_loc[idx], OPT_Wsizeof_pointer_memaccess,
 			"argument to % in %qD call is the same "
 			"expression as the source; did you mean to use "
diff --git a/gcc/calls.c b/gcc/calls.c
index 1f2cde6..8b86c8a 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -50,6 +50,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-chkp.h"
 #include "tree-vrp.h"
 #include "tree-ssanames.h"
+#include "tree-ssa-strlen.h"
 #include "rtl-chkp.h"
 #include "intl.h"
 #include "stringpool.h"
@@ -1623,8 +1624,10 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
 
   /* It's safe to call "bounded" string functions with a non-string
  argument since the functions provide an explicit bound for this
- purpose.  */
-  switch (DECL_FUNCTION_CODE (fndecl))
+ purpose.  The exception is strncat where the bound may refer to
+ either the destination or the source.  */
+  int fncode = DECL_FUNCTION_CODE (fndecl);
+  switch (fncode)
 {
 case BUILT_IN_STRCMP:
 case BUILT_IN_STRNCMP:
@@ -1645,6 +1648,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
   }
   /* Fall through.  */
 
+case BUILT_IN_STRNCAT:
 case BUILT_IN_STPNCPY:
 case BUILT_IN_STPNCPY_CHK:
 case BUILT_IN_STRNCPY:
@@ -1743,15 +1747,36 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
   if (!decl)
 	continue;
 
-  tree type = TREE_TYPE (decl);
-
   /* The maximum number of array elements accessed.  */
   offset_int wibnd = 0;
-  if (bndrng[0])
+
+  if (argno && fncode == BUILT_IN_STRNCAT)
+	{
+	  /* See if the bound in strncat is derived from the length
+	 of the strlen of the destination (as it's expected to be).
+	 If so, reset BOUND and FNCODE to trigger a warning.  */
+	  tree dstarg = CALL_EXPR_ARG (exp, 0);
+	  if (is_strlen_related_p (dstarg, bound))
+	{
+	  /* The bound applies to the destination, not to the source,
+		 so reset these to trigger a warning without mentioning
+		 the bound.  */
+	 

[PATCH] add udivhi3, umodhi3 functions to libgcc

2018-05-29 Thread Paul Koning
This patch adds two files which implement HImode unsigned divide 
and mod for GCC on platforms where that is needed and not provided
in hardware.  The code is lifted from the corresponding SImode
functions, with the obvious tweaks.

I'm not sure if I can commit this.

paul

2018-05-29  Paul Koning  

* udivhi3.c: New file.
* udivmodhi4.c: New file.
* config/pdp11/t-pdp11 (LIB2ADD): Add the above files.

Index: config/pdp11/t-pdp11
===
--- config/pdp11/t-pdp11(revision 260806)
+++ config/pdp11/t-pdp11(working copy)
@@ -1,5 +1,7 @@
 LIB2ADD = $(srcdir)/udivmod.c \
  $(srcdir)/udivmodsi4.c \
+ $(srcdir)/udivhi3.c \
+ $(srcdir)/udivmodhi4.c \
  $(srcdir)/memcmp.c \
  $(srcdir)/memcpy.c \
  $(srcdir)/memmove.c \
Index: udivhi3.c
===
--- udivhi3.c   (nonexistent)
+++ udivhi3.c   (working copy)
@@ -0,0 +1,37 @@
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
+
+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
+.  */
+
+short udivmodhi4 ();
+
+short
+__udivhi3 (short a, short b)
+{
+  return udivmodhi4 (a, b, 0);
+}
+
+short
+__umodhi3 (short a, short b)
+{
+  return udivmodhi4 (a, b, 1);
+}
+

Property changes on: udivhi3.c
___
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: udivmodhi4.c
===
--- udivmodhi4.c(nonexistent)
+++ udivmodhi4.c(working copy)
@@ -0,0 +1,47 @@
+/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
+
+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
+.  */
+
+unsigned short
+udivmodhi4(unsigned short num, unsigned short den, int modwanted)
+{
+  unsigned short bit = 1;
+  unsigned short res = 0;
+
+  while (den < num && bit && !(den & (1<<15)))
+{
+  den <<=1;
+  bit <<=1;
+}
+  while (bit)
+{
+  if (num >= den)
+   {
+ num -= den;
+ res |= bit;
+   }
+  bit >>=1;
+  den >>=1;
+}
+  if (modwanted) return num;
+  return res;
+}

Property changes on: udivmodhi4.c
___
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property



Re: [PATCH] [MSP430] Allow interrupt handers to be static and fix __interrupt__ attribute causing an ICE

2018-05-29 Thread DJ Delorie


The reason I required interrupt handlers to be non-static is because the
linker builds the interrupt handler table using weak references.  If the
handler is static, it won't be added to the table, and never called.

So you'd need a test to ensure that the handler was properly entered
into the table as well.


[PATCH, i386]: Fix PR85950, Unsafe-math-optimizations regresses optimization using SSE4.1 roundss

2018-05-29 Thread Uros Bizjak
Hello!

Attached patch enables l2 for
TARGET_SSE4.1, and while there, also corrects operand 1 predicate of
rounds{s,d} instruction.

2018-05-29  Uros Bizjak  

PR target/85950
* config/i386/i386.md (l2):
Enable for TARGET_SSE4_1 and generate rounds{s,d} and cvtts{s,d}2si{,q}
sequence.
(sse4_1_round2): Use nonimmediate_operand
for operand 1 predicate.

testsuite/ChangeLog:

2018-05-29  Uros Bizjak  

PR target/85950
* gcc.target/i386/pr85950.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
Index: config/i386/i386.md
===
--- config/i386/i386.md (revision 260850)
+++ config/i386/i386.md (working copy)
@@ -16655,7 +16655,7 @@
 
 (define_insn "sse4_1_round2"
   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
-   (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
+   (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
   (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
  UNSPEC_ROUND))]
   "TARGET_SSE4_1"
@@ -17251,12 +17251,19 @@
 FIST_ROUNDING))
  (clobber (reg:CC FLAGS_REG))])]
   "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
-   && !flag_trapping_math"
+   && (TARGET_SSE4_1 || !flag_trapping_math)"
 {
-  if (TARGET_64BIT && optimize_insn_for_size_p ())
-FAIL;
+  if (TARGET_SSE4_1)
+{
+  rtx tmp = gen_reg_rtx (mode);
 
-  if (ROUND_ == ROUND_FLOOR)
+  emit_insn (gen_sse4_1_round2
+(tmp, operands[1], GEN_INT (ROUND_
+| ROUND_NO_EXC)));
+  emit_insn (gen_fix_trunc2
+(operands[0], tmp));
+}
+  else if (ROUND_ == ROUND_FLOOR)
 ix86_expand_lfloorceil (operands[0], operands[1], true);
   else if (ROUND_ == ROUND_CEIL)
 ix86_expand_lfloorceil (operands[0], operands[1], false);
Index: testsuite/gcc.target/i386/pr85950.c
===
--- testsuite/gcc.target/i386/pr85950.c (nonexistent)
+++ testsuite/gcc.target/i386/pr85950.c (working copy)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.1 -mfpmath=sse" } */
+
+double floor (double);
+double ceil (double);
+
+int ifloor (double x) { return floor (x); }
+int iceil (double x) { return ceil (x); }
+
+#ifdef __x86_64__
+long long llfloor (double x) { return floor (x); }
+long long llceil (double x) { return ceil (x); }
+#endif
+  
+/* { dg-final { scan-assembler-times "roundsd" 2 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "roundsd" 4 { target { ! ia32 } } } } */


Re: [PATCH] consider MIN_EXPR in get_size_range() (PR 85888)

2018-05-29 Thread Martin Sebor

I do want to follow up on the optimization you referred to above.
After thinking about it some more I don't see what benefit it
could provide.  The value of the bound expression (LEN) ends up
computed at the call site and stored in a register that the library
strncmp has to read.  I can't think of any difference the MIN_EXPR
could make in the library, so the code as is seems strictly worse
than if it used the SSA_NAME directly instead.  Please let me know
if you don't agree (and what benefit you think it might provide).
Otherwise I'll open a bug to change it.


I've raised bug 85980 for this.

Martin


Re: [PATCH] PR target/85358 patch v2: Add target hook to prevent default widening

2018-05-29 Thread Michael Meissner
On Sat, May 26, 2018 at 08:13:04AM +0200, Richard Biener wrote:
> On May 25, 2018 8:49:47 PM GMT+02:00, Michael Meissner 
>  wrote:
> >I redid the patch to make the target hook only apply for scalar float
> >points,
> >and I removed all of the integer only subcases.
> >
> >I have checked this on a little endian Power8 system, and verified that
> >it
> >bootstraps correctly and there are no regressions.  I have just started
> >an
> >x86_64 build.  Assuming that build has no regressions, can I check this
> >into
> >GCC 9?  This bug appears in GCC 8, and I would like to back port this
> >patch to
> >GCC 8 as well before GCC 8.2 goes out.
> 
> What happens if you hack genmodes to not claim IFmode has any wider 
> relationship with other modes? 

It breaks the initialization of all of the types that initializes each of the
types from smallest to widest using the wider tables.

So you either need to have special types that are initialized without using the
wider table, or you need two sets of wider tables, one used by the
initialization sequences, and the other by normal binop/unop expansion.

There may be other dependencies that I'm not aware of (such as it must be
within the MIN_MODE_FLOAT and MAX_MODE_FLOAT range).

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797



Re: [PATCH][AArch64] Fix aarch64_ira_change_pseudo_allocno_class

2018-05-29 Thread Wilco Dijkstra
James Greenhalgh wrote:

> > Add a missing ? to aarch64_get_lane to fix a failure in the testsuite.
>
> > I'd prefer more detail than this for a workaround; which test, why did it
> > start to fail, why is this the right solution, etc.

It was gcc.target/aarch64/vect_copy_lane_1.c generating:

test_copy_laneq_f64:
    umov    x0, v1.d[1]
    fmov    d0, x0
    ret

For some reason returning a double uses DImode temporaries, so it's essential
to prefer FP_REGS here and mark the lane copy correctly.

Wilco


Re: [PATCH GCC][6/6]Restrict predcom using register pressure information

2018-05-29 Thread Bin.Cheng
On Tue, May 29, 2018 at 6:18 PM, David Malcolm  wrote:
> On Tue, 2018-05-29 at 17:04 +0100, Bin.Cheng wrote:
>> On Fri, May 4, 2018 at 5:24 PM, Bin Cheng  wrote:
>> > Hi,
>> > This patch restricts predcom pass using register pressure
>> > information.
>> > In case of high register pressure, we now prune additional chains
>> > as well
>> > as disable unrolling in predcom.  In generally, I think this patch
>> > set is
>> > useful.
>> >
>> > Bootstrap and test on x86_64 ongoing.  Any comments?
>>
>> Simple update in line with changes in previous patch.
>>
>> Thanks,
>> bin
>> >
>> > Thanks,
>> > bin
>> > 2018-04-27  Bin Cheng  
>> >
>> > * tree-predcom.c (stor-layout.h, tree-ssa-live.h): Include.
>> > (REG_RELAX_RATIO, prune_chains): New.
>> > (tree_predictive_commoning_loop): Compute reg pressure
>> > using class
>> > region.  Prune chains based on reg pressure.  Force to not
>> > unroll
>> > if reg pressure is high.
>
> [...snip...]
>
>> @@ -3239,6 +3301,11 @@ tree_predictive_commoning_loop (struct loop *loop)
>>/* Try to combine the chains that are always worked with together.  */
>>try_combine_chains (loop, );
>>
>> +  region = new lr_region (loop, max_pressure, NULL, NULL, NULL);
>> +  high_pressure_p = region->calculate_pressure ();
>> +  delete region;
>> +  prune_chains (, max_pressure);
>> +
>
> Possibly a silly question, but why the new/delete of "region" here?
> Couldn't this just be an on-stack object, with something like:
Yes, right.  It contained dynamically allocated memory before, so made
early deleting.  Now a local object will do.

Thanks,
bin
>
>   lr_region region (loop, max_pressure, NULL, NULL, NULL);
>   high_pressure_p = region.calculate_pressure ();
>   prune_chains (, max_pressure);
>
> or:
>
>   {
> lr_region region (loop, max_pressure, NULL, NULL, NULL);
> high_pressure_p = region.calculate_pressure ();
>   }
>   prune_chains (, max_pressure);
>
> if it's important to do the cleanup before prune_chains?
>
> Dave


[PATCH] Qualify another call in

2018-05-29 Thread Jonathan Wakely

* include/std/variant (__erased_dtor): Qualify call to __get.

Tested powerpc64le-linux, committed to trunk. Backports to follow.

commit a79e92a05636a5fee047fb6dfa8c839ab93ee35f
Author: Jonathan Wakely 
Date:   Tue May 29 18:04:57 2018 +0100

Qualify another call in 

* include/std/variant (__erased_dtor): Qualify call to __get.

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index c0212404bb2..63eafdd58e5 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -249,7 +249,7 @@ namespace __variant
   template
 void
 __erased_dtor(_Variant&& __v)
-{ std::_Destroy(std::__addressof(__get<_Np>(__v))); }
+{ std::_Destroy(std::__addressof(__variant::__get<_Np>(__v))); }
 
   template
 void


Re: [PATCH GCC][6/6]Restrict predcom using register pressure information

2018-05-29 Thread David Malcolm
On Tue, 2018-05-29 at 17:04 +0100, Bin.Cheng wrote:
> On Fri, May 4, 2018 at 5:24 PM, Bin Cheng  wrote:
> > Hi,
> > This patch restricts predcom pass using register pressure
> > information.
> > In case of high register pressure, we now prune additional chains
> > as well
> > as disable unrolling in predcom.  In generally, I think this patch
> > set is
> > useful.
> > 
> > Bootstrap and test on x86_64 ongoing.  Any comments?
> 
> Simple update in line with changes in previous patch.
> 
> Thanks,
> bin
> > 
> > Thanks,
> > bin
> > 2018-04-27  Bin Cheng  
> > 
> > * tree-predcom.c (stor-layout.h, tree-ssa-live.h): Include.
> > (REG_RELAX_RATIO, prune_chains): New.
> > (tree_predictive_commoning_loop): Compute reg pressure
> > using class
> > region.  Prune chains based on reg pressure.  Force to not
> > unroll
> > if reg pressure is high.

[...snip...]

> @@ -3239,6 +3301,11 @@ tree_predictive_commoning_loop (struct loop *loop)
>/* Try to combine the chains that are always worked with together.  */
>try_combine_chains (loop, );
>  
> +  region = new lr_region (loop, max_pressure, NULL, NULL, NULL);
> +  high_pressure_p = region->calculate_pressure ();
> +  delete region;
> +  prune_chains (, max_pressure);
> +

Possibly a silly question, but why the new/delete of "region" here?
Couldn't this just be an on-stack object, with something like:

  lr_region region (loop, max_pressure, NULL, NULL, NULL);
  high_pressure_p = region.calculate_pressure ();
  prune_chains (, max_pressure);

or:

  {
lr_region region (loop, max_pressure, NULL, NULL, NULL);
high_pressure_p = region.calculate_pressure ();
  }
  prune_chains (, max_pressure);

if it's important to do the cleanup before prune_chains?

Dave


Re: C++ PATCH for c++/85883, class tmpl args deduction fail with new

2018-05-29 Thread Jason Merrill
OK.

On Tue, May 29, 2018 at 11:55 AM, Marek Polacek  wrote:
> On Fri, May 25, 2018 at 01:58:53PM -0400, Jason Merrill wrote:
>> > + /* For the rest, e.g. new A(1, 2, 3), create a list.  */
>> > + else if (len > 1)
>> > +   {
>> > + unsigned int n;
>> > + tree t;
>> > + FOR_EACH_VEC_ELT (**init, n, t)
>> > +   {
>> > + t = resolve_nondeduced_context (t, complain);
>> > + d_init = chainon (d_init, build_tree_list (NULL_TREE, 
>> > t));
>>
>> Using chainon here means that for each element, we have to walk the
>> whole list to find the end.  See build_tree_list_vec.
>
> Good point.  Fixed here:
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2018-05-29  Marek Polacek  
>
> PR c++/85883
> * init.c (build_new): Handle deducing a class with new
> with more than one argument.
>
> * g++.dg/cpp1z/class-deduction55.C: New test.
> * g++.dg/cpp1z/class-deduction56.C: New test.
> * g++.dg/cpp1z/class-deduction57.C: New test.
>
> diff --git gcc/cp/init.c gcc/cp/init.c
> index 3f1e49bae21..da80e07f65b 100644
> --- gcc/cp/init.c
> +++ gcc/cp/init.c
> @@ -3585,11 +3585,27 @@ build_new (vec **placement, tree type, 
> tree nelts,
>if (auto_node)
> {
>   tree d_init = NULL_TREE;
> - if (vec_safe_length (*init) == 1)
> + const size_t len = vec_safe_length (*init);
> + /* E.g. new auto(x) must have exactly one element, or
> +a {} initializer will have one element.  */
> + if (len == 1)
> {
>   d_init = (**init)[0];
>   d_init = resolve_nondeduced_context (d_init, complain);
> }
> + /* For the rest, e.g. new A(1, 2, 3), create a list.  */
> + else if (len > 1)
> +   {
> + unsigned int n;
> + tree t;
> + tree *pp = _init;
> + FOR_EACH_VEC_ELT (**init, n, t)
> +   {
> + t = resolve_nondeduced_context (t, complain);
> + *pp = build_tree_list (NULL_TREE, t);
> + pp = _CHAIN (*pp);
> +   }
> +   }
>   type = do_auto_deduction (type, d_init, auto_node, complain);
> }
>  }
> diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction55.C 
> gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
> index e69de29bb2d..a93d7203681 100644
> --- gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
> +++ gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
> @@ -0,0 +1,15 @@
> +// PR c++/85883
> +// { dg-options -std=c++17 }
> +
> +template 
> +struct Bar
> +{
> +  Bar(T) { }
> +};
> +
> +int
> +main ()
> +{
> +  auto x = Bar(1);
> +  auto y = new Bar(3);
> +}
> diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction56.C 
> gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
> index e69de29bb2d..71dbfa1904d 100644
> --- gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
> +++ gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
> @@ -0,0 +1,15 @@
> +// PR c++/85883
> +// { dg-options -std=c++17 }
> +
> +template 
> +struct Bar
> +{
> +  Bar(T1, T2) { }
> +};
> +
> +int
> +main ()
> +{
> +  auto x = Bar(1, 2);
> +  auto y = new Bar(3, 4);
> +}
> diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction57.C 
> gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
> index e69de29bb2d..200ba6c3536 100644
> --- gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
> +++ gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
> @@ -0,0 +1,15 @@
> +// PR c++/85883
> +// { dg-options -std=c++17 }
> +
> +template 
> +struct Bar
> +{
> +  Bar(T1, T2, T3) { }
> +};
> +
> +int
> +main ()
> +{
> +  auto x = Bar(1, 2, 3);
> +  auto y = new Bar(3, 4, 5);
> +}


Re: [PATCH] allow more strncat calls with -Wstringop-truncation (PR 85700)

2018-05-29 Thread Martin Sebor

Ping: https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01189.html

On 05/22/2018 07:40 PM, Martin Sebor wrote:

Here's another small refinement to -Wstringop-truncation to
avoid diagnosing more arguably "safe" cases of strncat() that
match the expected pattern of

  strncat (d, s, sizeof d - strlen (d) - 1);

such as

  extern char a[4];
  strncat (a, "12", sizeof d - strlen (a) - 1);

Since the bound is derived from the length of the destination
as GCC documents is the expected use, the call should probably
not be diagnosed even though truncation is possible.

The trouble with strncat is that it specifies a single count
that can be (and has been) used to specify either the remaining
space in the destination or the maximum number of characters
to append, but not both.  It's nearly impossible to tell for
certain which the author meant, and if it's safe, hence all
this fine-tuning.  I suspect this isn't the last tweak, either.

In any event, I'd like to commit the patch to both trunk and
gcc-8-branch.  The bug isn't marked regression but I suppose
it could (should) well be considered one.

Martin




backport fix for PR 85623 to GCC 8

2018-05-29 Thread Martin Sebor

As discussed at (*) I'd like to backport the following patch
to GCC 8 to suppress a class of -Wstringop-truncation warnings.
If there are no concerns/objections I will go ahead and commit
it this week.

https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00509.html

Thanks
Martin

*) https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01170.html


Re: [PATCH GCC][6/6]Restrict predcom using register pressure information

2018-05-29 Thread Bin.Cheng
On Fri, May 4, 2018 at 5:24 PM, Bin Cheng  wrote:
> Hi,
> This patch restricts predcom pass using register pressure information.
> In case of high register pressure, we now prune additional chains as well
> as disable unrolling in predcom.  In generally, I think this patch set is
> useful.
>
> Bootstrap and test on x86_64 ongoing.  Any comments?
Simple update in line with changes in previous patch.

Thanks,
bin
>
> Thanks,
> bin
> 2018-04-27  Bin Cheng  
>
> * tree-predcom.c (stor-layout.h, tree-ssa-live.h): Include.
> (REG_RELAX_RATIO, prune_chains): New.
> (tree_predictive_commoning_loop): Compute reg pressure using class
> region.  Prune chains based on reg pressure.  Force to not unroll
> if reg pressure is high.
From b78c779907b98930fc4b36e5558d6f315bb4475b Mon Sep 17 00:00:00 2001
From: Bin Cheng 
Date: Wed, 25 Apr 2018 16:30:41 +0100
Subject: [PATCH 6/6] pcom-reg-pressure-20180428

---
 gcc/tree-predcom.c | 74 ++
 1 file changed, 74 insertions(+)

diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index aeadbf7..60316e9 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -217,6 +217,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "ssa.h"
 #include "gimple-pretty-print.h"
+#include "stor-layout.h"
 #include "alias.h"
 #include "fold-const.h"
 #include "cfgloop.h"
@@ -227,6 +228,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-loop-ivopts.h"
 #include "tree-ssa-loop-manip.h"
 #include "tree-ssa-loop-niter.h"
+#include "tree-ssa-live.h"
 #include "tree-ssa-loop.h"
 #include "tree-into-ssa.h"
 #include "tree-dfa.h"
@@ -242,6 +244,10 @@ along with GCC; see the file COPYING3.  If not see
 
 #define MAX_DISTANCE (target_avail_regs[GENERAL_REGS] < 16 ? 4 : 8)
 
+/* The ratio by which register pressure check is relaxed.  */
+
+#define REG_RELAX_RATIO (2)
+
 /* Data references (or phi nodes that carry data reference values across
loop iterations).  */
 
@@ -3156,6 +3162,59 @@ insert_init_seqs (struct loop *loop, vec chains)
   }
 }
 
+/* Prune chains causing high register pressure.  */
+
+static void
+prune_chains (vec *chains, unsigned *max_pressure)
+{
+  bool pruned_p = false;
+  machine_mode mode;
+  enum reg_class cl;
+  unsigned i, new_pressure;
+
+  for (i = 0; i < chains->length ();)
+{
+  chain_p chain = (*chains)[i];
+  /* Always allow combined chain and zero-length chain.  */
+  if (chain->combined || chain->type == CT_COMBINATION
+	  || chain->length == 0 || chain->type == CT_STORE_STORE)
+	{
+	  i++;
+	  continue;
+	}
+
+  gcc_assert (chain->refs.length () > 0);
+  mode = TYPE_MODE (TREE_TYPE (chain->refs[0]->ref->ref));
+  /* Bypass chain that doesn't contribute to any reg_class, although
+	 something could be wrong when mapping type mode to reg_class.  */
+  if (ira_mode_classes[mode] == NO_REGS)
+	{
+	  i++;
+	  continue;
+	}
+
+  cl = ira_pressure_class_translate[ira_mode_classes[mode]];
+  /* Prune chain if it causes higher register pressure than available
+	 registers; otherwise keep the chain and update register pressure
+	 information.  */
+  new_pressure = max_pressure[cl] + chain->length - 1;
+  if (new_pressure <= target_avail_regs[cl] * REG_RELAX_RATIO)
+	{
+	  i++;
+	  max_pressure[cl] = new_pressure;
+	}
+  else
+	{
+	  release_chain (chain);
+	  chains->unordered_remove (i);
+	  pruned_p = true;
+	}
+}
+
+  if (pruned_p && dump_file && (dump_flags & TDF_DETAILS))
+fprintf (dump_file, "Prune chain because of high reg pressure\n");
+}
+
 /* Performs predictive commoning for LOOP.  Sets bit 1<<0 of return value
if LOOP was unrolled; Sets bit 1<<1 of return value if loop closed ssa
form was corrupted.  */
@@ -3171,6 +3230,9 @@ tree_predictive_commoning_loop (struct loop *loop)
   struct tree_niter_desc desc;
   bool unroll = false, loop_closed_ssa = false;
   edge exit;
+  lr_region *region;
+  unsigned max_pressure[N_REG_CLASSES];
+  bool high_pressure_p;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
 fprintf (dump_file, "Processing loop %d\n",  loop->num);
@@ -3239,6 +3301,11 @@ tree_predictive_commoning_loop (struct loop *loop)
   /* Try to combine the chains that are always worked with together.  */
   try_combine_chains (loop, );
 
+  region = new lr_region (loop, max_pressure, NULL, NULL, NULL);
+  high_pressure_p = region->calculate_pressure ();
+  delete region;
+  prune_chains (, max_pressure);
+
   insert_init_seqs (loop, chains);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -3250,6 +3317,13 @@ tree_predictive_commoning_loop (struct loop *loop)
   /* Determine the unroll factor, and if the loop should be unrolled, ensure
  that its number of iterations is divisible by the factor.  */
   unroll_factor = determine_unroll_factor (chains);
+  /* Force to not unroll if register pressure is high.  */
+  if 

Re: [PATCH GCC][5/6]implement live range, reg pressure computation class

2018-05-29 Thread Bin.Cheng
On Mon, May 28, 2018 at 12:22 PM, Richard Biener
 wrote:
> On Fri, May 18, 2018 at 1:57 PM Bin.Cheng  wrote:
>
>> On Fri, May 4, 2018 at 5:23 PM, Bin Cheng  wrote:
>> > Hi,
>> > Based on previous patch, this one implements live range, reg pressure
> computation
>> > class in tree-ssa-live.c.  The user would only need to instantiate the
> class and
>> > call the computation interface as in next patch.
>> > During the work, I think it's also worthwhile to classify all live
> range and coalesce
>> > data structures and algorithms in the future.
>> >
>> > Bootstrap and test on x86_64 and AArch64 ongoing.  Any comments?
>
>> Updated patch in line with change of previous patch.

Thanks for reviewing.

>
> So I see you do not want to expose the magic '16' in pressure_threshold to
> the
> user because in theory the target should provide enough information.  But
> why
> need it at all?  Also
Typically, we consider register pressure high if it exceeds available registers,
while for extreme targets, for example, with only 4~5 available registers, do we
consider a loop region with register pressure 8 as high?  It could be
a very small
loop and if we do, that would basically disable optimizations.  So
here the number
is used as an absolute criteria for high register pressure.  Given
max_pressure is
computed on GIMPLE and there might be scheduling issue exaggerating register
pressure, I chose this relative big number (16).

>
> +  /* Calculate maximum reg pressure information for region and store it in
> + MAX_PRESSURE.  Return true if the reg pressure is high.  */
> +  bool calculate_pressure (unsigned *max_pressure);
>
> it looks like you expect a [N_REG_CLASSES] sized output array here, that's
> not
> clear from the documentation.
>
> The output information is a little shallow - I'd be interested in the
> number of
> live through region regs being separated from live in / out.  That is, can
> you
> add additional outputs to the above and thus make it more like
>
>bool calculate_pressure (unsigned max_pressure[], unsigned live_in[],
> unsigned live_out[], unsigned live_through[]);
Done.

>
> with the numbers being on the region?
>
> It also seems to be a fire-and-forget class so I wonder why liveness is not
> computed at construction
> time so intermediate data can be freed and only the results stored?
>
> stmt_lr_info -> id seems to be unused?  In fact what is the point of this
> structure (and the per stmt bitmap)?
> It looks write-only to me...
Yes, this was legacy code from my draft patch where it computes live ranges
for within-block scheduling.  Now it's all removed/simplified.

Any comment on this version?  Also I will withhold it till ISA
interface exposing issue addressed.

Thanks,
bin

2018-05-29  Bin Cheng  

* tree-ssa-live.c (memmodel.h, ira.h, tree-ssa-coalesce.h): Include.
(lr_region::update_live_range_by_stmt): New.
(lr_region::count_pressure_for_live_ranges): New.
(lr_region::calculate_coalesced_pressure): New.
(lr_region::calculate_pressure): New.
* tree-ssa-live.h (class lr_region): New class.
From a51dc3bde02a24d4a6d17b5f14d13859a8766824 Mon Sep 17 00:00:00 2001
From: Bin Cheng 
Date: Fri, 4 May 2018 09:42:04 +0100
Subject: [PATCH 5/6] region-reg-pressure-20180528

---
 gcc/tree-ssa-live.c | 140 
 gcc/tree-ssa-live.h |  84 +++
 2 files changed, 224 insertions(+)

diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 7447f7a..830b050 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "backend.h"
 #include "rtl.h"
+#include "memmodel.h"
+#include "ira.h"
 #include "tree.h"
 #include "gimple.h"
 #include "timevar.h"
@@ -34,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dfa.h"
 #include "dumpfile.h"
 #include "tree-ssa-live.h"
+#include "tree-ssa-coalesce.h"
 #include "debug.h"
 #include "tree-ssa.h"
 #include "ipa-utils.h"
@@ -1200,6 +1203,143 @@ calculate_live_ranges (var_map map, bool want_livein)
 }
 
 
+/* Implementation for class lr_region.  */
+
+void
+lr_region::update_live_range_by_stmt (gimple *stmt, bitmap live_ranges,
+  unsigned pressure[])
+{
+  int p;
+  tree var;
+  ssa_op_iter iter;
+
+  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
+{
+  p = var_to_partition (m_varmap, var);
+  gcc_assert (p != NO_PARTITION);
+  if (bitmap_clear_bit (live_ranges, p))
+	pressure[ira_mode_classes[TYPE_MODE (TREE_TYPE (var))]]--;
+}
+  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
+{
+  p = var_to_partition (m_varmap, var);
+  gcc_assert (p != NO_PARTITION);
+  if (bitmap_set_bit (live_ranges, p))
+	pressure[ira_mode_classes[TYPE_MODE (TREE_TYPE (var))]]++;
+}
+}
+
+void
+lr_region::count_pressure_for_live_ranges (bitmap live_ranges,
+	   unsigned pressure[])
+{
+  unsigned i, 

Re: C++ PATCH for c++/85883, class tmpl args deduction fail with new

2018-05-29 Thread Marek Polacek
On Fri, May 25, 2018 at 01:58:53PM -0400, Jason Merrill wrote:
> > + /* For the rest, e.g. new A(1, 2, 3), create a list.  */
> > + else if (len > 1)
> > +   {
> > + unsigned int n;
> > + tree t;
> > + FOR_EACH_VEC_ELT (**init, n, t)
> > +   {
> > + t = resolve_nondeduced_context (t, complain);
> > + d_init = chainon (d_init, build_tree_list (NULL_TREE, t));
> 
> Using chainon here means that for each element, we have to walk the
> whole list to find the end.  See build_tree_list_vec.

Good point.  Fixed here:

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-05-29  Marek Polacek  

PR c++/85883
* init.c (build_new): Handle deducing a class with new
with more than one argument.

* g++.dg/cpp1z/class-deduction55.C: New test.
* g++.dg/cpp1z/class-deduction56.C: New test.
* g++.dg/cpp1z/class-deduction57.C: New test.

diff --git gcc/cp/init.c gcc/cp/init.c
index 3f1e49bae21..da80e07f65b 100644
--- gcc/cp/init.c
+++ gcc/cp/init.c
@@ -3585,11 +3585,27 @@ build_new (vec **placement, tree type, 
tree nelts,
   if (auto_node)
{
  tree d_init = NULL_TREE;
- if (vec_safe_length (*init) == 1)
+ const size_t len = vec_safe_length (*init);
+ /* E.g. new auto(x) must have exactly one element, or
+a {} initializer will have one element.  */
+ if (len == 1)
{
  d_init = (**init)[0];
  d_init = resolve_nondeduced_context (d_init, complain);
}
+ /* For the rest, e.g. new A(1, 2, 3), create a list.  */
+ else if (len > 1)
+   {
+ unsigned int n;
+ tree t;
+ tree *pp = _init;
+ FOR_EACH_VEC_ELT (**init, n, t)
+   {
+ t = resolve_nondeduced_context (t, complain);
+ *pp = build_tree_list (NULL_TREE, t);
+ pp = _CHAIN (*pp);
+   }
+   }
  type = do_auto_deduction (type, d_init, auto_node, complain);
}
 }
diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction55.C 
gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
index e69de29bb2d..a93d7203681 100644
--- gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
+++ gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
@@ -0,0 +1,15 @@
+// PR c++/85883
+// { dg-options -std=c++17 }
+
+template 
+struct Bar
+{
+  Bar(T) { }
+};
+
+int
+main ()
+{
+  auto x = Bar(1);
+  auto y = new Bar(3);
+}
diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction56.C 
gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
index e69de29bb2d..71dbfa1904d 100644
--- gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
+++ gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
@@ -0,0 +1,15 @@
+// PR c++/85883
+// { dg-options -std=c++17 }
+
+template 
+struct Bar
+{
+  Bar(T1, T2) { }
+};
+
+int
+main ()
+{
+  auto x = Bar(1, 2);
+  auto y = new Bar(3, 4);
+}
diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction57.C 
gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
index e69de29bb2d..200ba6c3536 100644
--- gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
+++ gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
@@ -0,0 +1,15 @@
+// PR c++/85883
+// { dg-options -std=c++17 }
+
+template 
+struct Bar
+{
+  Bar(T1, T2, T3) { }
+};
+
+int
+main ()
+{
+  auto x = Bar(1, 2, 3);
+  auto y = new Bar(3, 4, 5);
+}


Re: [PATCH , rs6000] Add builtin tests for vec_madds, vec_extract_fp32_from_shortl and vec_extract_fp32_from_shorth, vec_xst_be

2018-05-29 Thread Carl Love
GCC Maintainers:

The patch has been updated to address Segher's comment for test file
builtins-3-p9.c be qualified for le.

The patch was retested on:

powerpc64le-unknown-linux-gnu (Power 8 LE)   
powerpc64le-unknown-linux-gnu (Power 9 LE)
powerpc64-unknown-linux-gnu (Power 8 BE)

With no regressions.

Please let me know if the patch looks OK for GCC mainline.

 Carl Love

--

gcc/testsuite/ChangeLog:

2018-05-29  Carl Love  
* gcc.target/powerpc/altivec-35.c (foo): Add builtin test vec_madds.
* gcc.target/powerpc/builtins-3-p9.c (main): Add tests for
vec_extract_fp32_from_shortl and vec_extract_fp32_from_shorth.
* gcc.target/powerpc/builtins-6-runnable.c (main): Fix typo for output.
Add vec_xst_be for signed and unsigned arguments.
---
 gcc/testsuite/gcc.target/powerpc/altivec-35.c  |  4 ++
 .../gcc.target/powerpc/builtins-3-p9-runnable.c| 16 ++
 gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c   |  2 +-
 .../gcc.target/powerpc/builtins-6-runnable.c   | 62 +++---
 4 files changed, 75 insertions(+), 9 deletions(-)

diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-35.c 
b/gcc/testsuite/gcc.target/powerpc/altivec-35.c
index 46e8eed..0836528 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-35.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-35.c
@@ -1,3 +1,4 @@
+
 /* { dg-do compile } */
 /* { dg-require-effective-target powerpc_altivec_ok } */
 /* { dg-options "-maltivec -mno-vsx -mno-power8-vector -O0" } */
@@ -19,7 +20,10 @@ void foo (vector signed int *vsir,
   *vssr++ = vec_madd (vssa, vusb, vusc);
   *vssr++ = vec_madd (vusa, vssb, vssc);
   *vusr++ = vec_madd (vusa, vusb, vusc);
+
+  *vssr++ = vec_madds (vssa, vssb, vssc);
 }
 
 /* { dg-final { scan-assembler-times "vaddcuw" 1 } } */
 /* { dg-final { scan-assembler-times "vmladduhm" 4 } } */
+/* { dg-final { scan-assembler-times "vmhaddshs" 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-3-p9-runnable.c 
b/gcc/testsuite/gcc.target/powerpc/builtins-3-p9-runnable.c
index 3b67e53..e29c97c 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtins-3-p9-runnable.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-3-p9-runnable.c
@@ -32,4 +32,20 @@ int main() {
   if (vfr[i] != vfexpt[i])
  abort();
}
+
+   vfexpt = (vector float){1.0, -2.0, 0.0, 8.5};
+   vfr = vec_extract_fp32_from_shorth(vusha);
+
+   for (i=0; i<4; i++) {
+  if (vfr[i] != vfexpt[i])
+    abort();
+   }
+
+   vfexpt = (vector float){1.5, 0.5, 1.25, -0.25};
+   vfr = vec_extract_fp32_from_shortl(vusha);
+
+   for (i=0; i<4; i++) {
+  if (vfr[i] != vfexpt[i])
+    abort();
+   } 
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c 
b/gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c
index 146f8b7..a175890 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-3-p9.c
@@ -1,4 +1,4 @@
-/* { dg-do compile } */
+/* { dg-do compile  { target { le } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
 /* { dg-options "-mcpu=power9 -O1" } */
 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-6-runnable.c 
b/gcc/testsuite/gcc.target/powerpc/builtins-6-runnable.c
index 5d31312..380a11a 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtins-6-runnable.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-6-runnable.c
@@ -60,11 +60,11 @@ void print_uc (vector unsigned char vec_expected,
 {
   int i;
 
-  printf("expected signed char data\n");
+  printf("expected unsigned char data\n");
   for (i = 0; i < 16; i++)
 printf(" %d,", vec_expected[i]);
 
-  printf("\nactual signed char data\n");
+  printf("\nactual unsigned char data\n");
   for (i = 0; i < 16; i++)
 printf(" %d,", vec_actual[i]);
   printf("\n");
@@ -197,13 +197,11 @@ void print_ull (vector unsigned long long vec_expected,
 
   printf("expected unsigned long long data\n");
   for (i = 0; i < 2; i++)
-     //printf(" %llu,", vec_expected[i]);
-printf(" 0x%llx,", vec_expected[i]);
+printf(" %llu,", vec_expected[i]);
 
   printf("\nactual unsigned long long data\n");
   for (i = 0; i < 2; i++)
-     //printf(" %llu,", vec_actual[i]);
-printf("0x %llx,", vec_actual[i]);
+printf(" %llu,", vec_actual[i]);
   printf("\n");
 }
 
@@ -745,6 +743,56 @@ int main() {
 #endif
  }
 
+   disp = 8;
+#ifdef __BIG_ENDIAN__
+   vec_si_expected1 = (vector signed int){  0, 0, -8, -7 };
+#else
+   vec_si_expected1 = (vector signed int){  0, 0, -5, -6 };
+#endif
+   store_data_si = (vector signed int){ -8, -7, -6, -5 };
+
+   for (i=0; i<4; i++)
+ vec_si_result1[i] = 0;
+
+   address_si = _si_result1[0];
+
+   vec_xst_be (store_data_si, disp, address_si);
+
+   if (result_wrong_si (vec_si_expected1, vec_si_result1))

Re: [AARCH64] Add support of ARMv8.4 in saphira for Qualcomm server part

2018-05-29 Thread Siddhesh Poyarekar
On 29 May 2018 at 21:17, James Greenhalgh  wrote:
> On Tue, May 29, 2018 at 05:01:42AM -0500, Sameera Deshpande wrote:
>> Hi!
>>
>> Please find attached the patch to add support of ARMv8.4 in saphira
>> for Qualcomm server part. Tested on aarch64, without any regressions.
>>
>> Ok for trunk?
>
> I'm trusting that this is the right thing to do for this core. As Siddhesh
> contributed the original patch; I'd like him to also sign off on this
> modification.
>
> OK for trunk with Siddhesh's ack.

LGTM too.

Thanks,
Siddhesh


Re: [PATCH , rs6000] Add missing builtin test cases, fix arguments to match specifications.

2018-05-29 Thread Carl Love
GCC maintainers:

The patch has been reworked again to take advantage of the le and be
selectors available, the separate BE and LE test files have been
combined into a single test file.  The result testing is now qualified
based on the le and be selectors.  This reduces the difficulty of
maintaining two separate files that are mostly similar.  The dg
directives have been updated to ensure the tests will run on 32-bit,
64-bit, le and be as appropriate.

The patch was tested by hand by doing the make -k with --
target_board=unix'{-m64,-m32}' for each of the test files to verify the
results for 32-bit and 64-bits.  Additionally, the standard full
regression test was done to verify the hand testing didn't miss
anything obvious.  The testing was done on

    powerpc64le-unknown-linux-gnu (Power 8 LE)   
powerpc64le-unknown-linux-gnu (Power 9 LE)
powerpc64-unknown-linux-gnu (Power 8 BE)

With no regressions.

Please let me know if the patch looks OK for GCC mainline.

 Carl Love



---

gcc/testsuite/ChangeLog:

2018-05-29  Carl Love  

* gcc.target/powerpc/altivec-12.c (main): Fix declaration of ucz
to make it consistent with the naming convention in the file.
* gcc.target/powerpc/altivec-7-be.c: Move BE specific checks
to altivec-7.c.  Delete file.
* gcc.target/powerpc/altivec-7-le.c: Move LE specific checks
to altivec-7.c.  Delete file.
* gcc.target/powerpc/altivec-7.h: Move to altivec-7.c.
* gcc.target/powerpc/altivec-7.c (main): Add vec_unpackh and
vec_unpackl tests.  Update instruction counts.
* gcc.target/powerpc/builtins-1-le.c: Move LE specific checks to
tests to builtins-1.c.
* gcc.target/powerpc/builtins-1-be.c: Move BE specific
tests to builtins-1.c.
* gcc.target/powerpc/builtins-1.h: Move to file builtins-1.c.
* gcc.target/powerpc/builtins-1.c (main): Add test case for vec_and.
vec_round, vec_rsqrt, vec_rsqrte, vec_mergee, vec_mergh, vec_mergo.
Remove vec_ctf tests returning double.  Remove vec_cts with
double args. Remove vec_sel with invalid arguments. Add tests for
vec_splat.
Add instruction counts for new tests.
* gcc.target/powerpc/builtins-3-runnable.c (main): Add test for
vec_doublee, vec_doubleo, vec_doublel, vec_doubleh, vec_signed,
vec_unsigned.
* gcc.target/powerpc/builtins-3.c:  Add tests 
test_sll_vuill_vuill_vuc,
test_sll_vsill_vsill_vuc.
* gcc.target/powerpc/p9-xxbr-2.c (rev_bool_long_long): Added test for
vec_revb.
* gcc.target/powerpc/vsx-7.h: Rename to vsx-7.c. Remove redundant
tests from altivec-7.h.
* gcc.target/powerpc/vsx-7-be.c: Remove file.
* gcc.target/powerpc/vsx-builtin-7.c: Add test functions splat_sc_s8,
splat_uc_u8, splat_ssi_s16, splat_usi_s16, splat_si_s32, splat_ui_u32,
splat_sll, splat_uc, splat_int128, splat_uint128.
Make second argument of vec_extract and vec_insert a signed int.
* gcc.target/powerpc/vsx-vector-5.c (vrint): Add vrint test for float
argument.
---
 gcc/testsuite/gcc.target/powerpc/altivec-12.c  |   2 +-
 gcc/testsuite/gcc.target/powerpc/altivec-7-be.c|  30 --
 gcc/testsuite/gcc.target/powerpc/altivec-7-le.c|  37 ---
 gcc/testsuite/gcc.target/powerpc/altivec-7.c   | 113 +++
 gcc/testsuite/gcc.target/powerpc/altivec-7.h   |  47 ---
 gcc/testsuite/gcc.target/powerpc/builtins-1-be.c   |  76 -
 gcc/testsuite/gcc.target/powerpc/builtins-1-le.c   |  71 
 gcc/testsuite/gcc.target/powerpc/builtins-1.c  | 368 +
 gcc/testsuite/gcc.target/powerpc/builtins-1.h  | 229 -
 .../gcc.target/powerpc/builtins-3-runnable.c   |  23 +-
 gcc/testsuite/gcc.target/powerpc/builtins-3.c  |  76 -
 gcc/testsuite/gcc.target/powerpc/p9-xxbr-2.c   |   8 +-
 gcc/testsuite/gcc.target/powerpc/vsx-7-be.c|  50 ---
 gcc/testsuite/gcc.target/powerpc/vsx-7.c   |  26 ++
 gcc/testsuite/gcc.target/powerpc/vsx-7.h   |  18 -
 gcc/testsuite/gcc.target/powerpc/vsx-builtin-7.c   | 160 ++---
 gcc/testsuite/gcc.target/powerpc/vsx-vector-5.c|  17 +-
 17 files changed, 708 insertions(+), 643 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/altivec-7-be.c
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/altivec-7-le.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/altivec-7.c
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/altivec-7.h
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/builtins-1-be.c
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/builtins-1-le.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/builtins-1.c
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/builtins-1.h
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-7-be.c
 create 

[PATCH][AArch64] Improve LDP/STP generation that requires a base register

2018-05-29 Thread Kyrill Tkachov

[sending on behalf of Jackson Woodruff]

Hi all,

This patch generalizes the formation of LDP/STP that require a base register.

In AArch64, LDP/STP instructions have different sized immediate offsets than
normal LDR/STR instructions. This part of the backend attempts to spot groups
of four LDR/STR instructions that can be turned into LDP/STP instructions by
using a base register.

Previously, we would only accept address pairs that were ordered in ascending
or descending order, and only strictly sequential loads/stores. In fact, the
instructions that we generate from this should be able to consider any order
of loads or stores (provided that they can be re-ordered). They should also be
able to accept non-sequential loads and stores provided that the two pairs of
addresses are amenable to pairing. The current code is also overly restrictive
on the range of addresses that are accepted, as LDP/STP instructions may take
negative offsets as well as positive ones.

This patch improves that by allowing us to accept all orders of loads/stores
that are valid, and extending the range that the LDP/STP addresses can reach.

OK for trunk?

Jackson

ChangeLog:

gcc/

2017-05-29  Jackson Woodruff  

* config/aarch64/aarch64.c (aarch64_host_wide_int_compare): New.
(aarch64_ldrstr_offset_compare): New.
(aarch64_operands_adjust_ok_for_ldpstp): Update to consider all
load/store orderings.
(aarch64_gen_adjusted_ldpstp): Likewise.

gcc/testsuite

2017-05-29  Jackson Woodruff  

* gcc.target/aarch64/simd/ldp_stp_9: New.
* gcc.target/aarch64/simd/ldp_stp_10: New.
* gcc.target/aarch64/simd/ldp_stp_11: New.
* gcc.target/aarch64/simd/ldp_stp_12: New.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index f60e0ad37565b044b3ffe446eebcc0f40f9d99db..4c352854c9b8c31e6e6229e375c1e61117c2b7e4 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -16935,6 +16935,50 @@ aarch64_swap_ldrstr_operands (rtx* operands, bool load)
 }
 }
 
+/* Taking X and Y to be HOST_WIDE_INT pointers, return the result of a
+   comparison between the two.  */
+int
+aarch64_host_wide_int_compare (const void *x, const void *y)
+{
+  return wi::cmps (* ((const HOST_WIDE_INT *) x),
+		   * ((const HOST_WIDE_INT *) y));
+}
+
+/* Taking X and Y to be pairs of RTX, one pointing to a MEM rtx and the
+   other pointing to a REG rtx containing an offset, compare the offsets
+   of the two pairs.
+
+   Return:
+
+	1 iff offset (X) > offset (Y)
+	0 iff offset (X) == offset (Y)
+	-1 iff offset (X) < offset (Y)  */
+int
+aarch64_ldrstr_offset_compare (const void *x, const void *y)
+{
+  const rtx * operands_1 = (const rtx *) x;
+  const rtx * operands_2 = (const rtx *) y;
+  rtx mem_1, mem_2, base, offset_1, offset_2;
+
+  if (MEM_P (operands_1[0]))
+mem_1 = operands_1[0];
+  else
+mem_1 = operands_1[1];
+
+  if (MEM_P (operands_2[0]))
+mem_2 = operands_2[0];
+  else
+mem_2 = operands_2[1];
+
+  /* Extract the offsets.  */
+  extract_base_offset_in_addr (mem_1, , _1);
+  extract_base_offset_in_addr (mem_2, , _2);
+
+  gcc_assert (offset_1 != NULL_RTX && offset_2 != NULL_RTX);
+
+  return wi::cmps (INTVAL (offset_1), INTVAL (offset_2));
+}
+
 /* Given OPERANDS of consecutive load/store, check if we can merge
them into ldp/stp by adjusting the offset.  LOAD is true if they
are load instructions.  MODE is the mode of memory operands.
@@ -16961,7 +17005,7 @@ aarch64_operands_adjust_ok_for_ldpstp (rtx *operands, bool load,
    scalar_mode mode)
 {
   enum reg_class rclass_1, rclass_2, rclass_3, rclass_4;
-  HOST_WIDE_INT offval_1, offval_2, offval_3, offval_4, msize;
+  HOST_WIDE_INT offvals[4], msize;
   rtx mem_1, mem_2, mem_3, mem_4, reg_1, reg_2, reg_3, reg_4;
   rtx base_1, base_2, base_3, base_4, offset_1, offset_2, offset_3, offset_4;
 
@@ -16977,8 +17021,12 @@ aarch64_operands_adjust_ok_for_ldpstp (rtx *operands, bool load,
   mem_4 = operands[7];
   gcc_assert (REG_P (reg_1) && REG_P (reg_2)
 		  && REG_P (reg_3) && REG_P (reg_4));
-  if (REGNO (reg_1) == REGNO (reg_2) || REGNO (reg_3) == REGNO (reg_4))
-	return false;
+
+  /* Do not attempt to merge the loads if the loads clobber each other.  */
+  for (int i = 0; i < 8; i += 2)
+	for (int j = i + 2; j < 8; j += 2)
+	  if (reg_overlap_mentioned_p (operands[i], operands[j]))
+	return false;
 }
   else
 {
@@ -17020,32 +17068,34 @@ aarch64_operands_adjust_ok_for_ldpstp (rtx *operands, bool load,
   || !rtx_equal_p (base_3, base_4))
 return false;
 
-  offval_1 = INTVAL (offset_1);
-  offval_2 = INTVAL (offset_2);
-  offval_3 = INTVAL (offset_3);
-  offval_4 = INTVAL (offset_4);
+  offvals[0] = INTVAL (offset_1);
+  offvals[1] = INTVAL (offset_2);
+  offvals[2] = INTVAL (offset_3);
+  offvals[3] = INTVAL (offset_4);
   msize = GET_MODE_SIZE (mode);
-  /* Check if the offsets are consecutive.  */
-  if ((offval_1 != (offval_2 + msize)
-   || offval_1 != 

Re: [C++ PATCH] Avoid bogus -Wunused-but-set* with structured binding (PR c++/85952)

2018-05-29 Thread Jason Merrill
OK.

On Tue, May 29, 2018 at 10:55 AM, Jakub Jelinek  wrote:
> On Tue, May 29, 2018 at 10:49:03AM -0400, Jason Merrill wrote:
>> >>   auto & [x,y] = a;
>> >>
>> >> but that should be added to the testcase.
>> >
>> > It is already there (in baz).
>>
>> Well, yes, but in baz a is an S, not an array; I see value and
>> reference cases for S, but only value for int array.
>
> Oops, yes, you're right.  Added qux then that tests array initializer
> and & qualifier.
>
> Ok with that change?
>
> 2018-05-29  Jakub Jelinek  
>
> PR c++/85952
> * init.c (build_aggr_init): For structured binding initialized from
> array call mark_rvalue_use on the initializer.
>
> * g++.dg/warn/Wunused-var-33.C: New test.
>
> --- gcc/cp/init.c.jj2018-05-25 14:34:41.0 +0200
> +++ gcc/cp/init.c   2018-05-28 19:04:10.504063972 +0200
> @@ -1678,6 +1678,7 @@ build_aggr_init (tree exp, tree init, in
>if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
> {
>   from_array = 1;
> + init = mark_rvalue_use (init);
>   if (init && DECL_P (init)
>   && !(flags & LOOKUP_ONLYCONVERTING))
> {
> --- gcc/testsuite/g++.dg/warn/Wunused-var-33.C.jj   2018-05-28 
> 19:32:00.236440573 +0200
> +++ gcc/testsuite/g++.dg/warn/Wunused-var-33.C  2018-05-29 16:52:21.322700629 
> +0200
> @@ -0,0 +1,37 @@
> +// PR c++/85952
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-Wunused-but-set-variable" }
> +
> +int
> +foo ()
> +{
> +  int a[2] = {1, 2};   // { dg-bogus "set but not used" } */
> +  auto [x, y] = a; // { dg-warning "structured bindings only available 
> with" "" { target c++14_down } }
> +  return x + y;
> +}
> +
> +struct S { int d, e; };
> +
> +int
> +bar ()
> +{
> +  S a = {1, 2};
> +  auto [x, y] = a; // { dg-warning "structured bindings only available 
> with" "" { target c++14_down } }
> +  return x + y;
> +}
> +
> +int
> +baz ()
> +{
> +  S a = {1, 2};
> +  auto & [x, y] = a;   // { dg-warning "structured bindings only available 
> with" "" { target c++14_down } }
> +  return x + y;
> +}
> +
> +int
> +qux ()
> +{
> +  int a[2] = {1, 2};
> +  auto & [x, y] = a;   // { dg-warning "structured bindings only available 
> with" "" { target c++14_down } }
> +  return x + y;
> +}
>
> Jakub


Re: [PATCH] consider MIN_EXPR in get_size_range() (PR 85888)

2018-05-29 Thread Martin Sebor

On 05/28/2018 03:11 AM, Richard Biener wrote:

On Fri, May 25, 2018 at 10:15 PM Martin Sebor  wrote:


Attached is revision 3 of the patch incorporating your
determine_value_range function with the requested changes.


I'm somewhat torn about removing the "basic" interface on SSA names
so can you please not change get_range_info for now and instead
use determine_value_range in get_size_range for now?


I can do that.  Can you explain why you're having second thoughts
about going this route?

FWIW: I've already made changes to most clients to get_range_info
to let them call the function for non-SSA arguments and have been
testing the (incremental) patch.  I haven't seen a dramatic increase
in the number of successful calls to the function as a result so it
doesn't seem like it would be too much of an improvement.  I did
notice that some calls end up returning a one-element range, i.e.,
N, N].  Unless callers are prepared to handle such ranges this could
expose bugs or optimization opportunities.  Is it worth finishing
this up?

Martin



Re: [C++ PATCH] Avoid bogus -Wunused-but-set* with structured binding (PR c++/85952)

2018-05-29 Thread Jakub Jelinek
On Tue, May 29, 2018 at 10:49:03AM -0400, Jason Merrill wrote:
> >>   auto & [x,y] = a;
> >>
> >> but that should be added to the testcase.
> >
> > It is already there (in baz).
> 
> Well, yes, but in baz a is an S, not an array; I see value and
> reference cases for S, but only value for int array.

Oops, yes, you're right.  Added qux then that tests array initializer
and & qualifier.

Ok with that change?

2018-05-29  Jakub Jelinek  

PR c++/85952
* init.c (build_aggr_init): For structured binding initialized from
array call mark_rvalue_use on the initializer.

* g++.dg/warn/Wunused-var-33.C: New test.

--- gcc/cp/init.c.jj2018-05-25 14:34:41.0 +0200
+++ gcc/cp/init.c   2018-05-28 19:04:10.504063972 +0200
@@ -1678,6 +1678,7 @@ build_aggr_init (tree exp, tree init, in
   if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
{
  from_array = 1;
+ init = mark_rvalue_use (init);
  if (init && DECL_P (init)
  && !(flags & LOOKUP_ONLYCONVERTING))
{
--- gcc/testsuite/g++.dg/warn/Wunused-var-33.C.jj   2018-05-28 
19:32:00.236440573 +0200
+++ gcc/testsuite/g++.dg/warn/Wunused-var-33.C  2018-05-29 16:52:21.322700629 
+0200
@@ -0,0 +1,37 @@
+// PR c++/85952
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wunused-but-set-variable" }
+
+int
+foo ()
+{
+  int a[2] = {1, 2};   // { dg-bogus "set but not used" } */
+  auto [x, y] = a; // { dg-warning "structured bindings only available 
with" "" { target c++14_down } }
+  return x + y;
+}
+
+struct S { int d, e; };
+
+int
+bar ()
+{
+  S a = {1, 2};
+  auto [x, y] = a; // { dg-warning "structured bindings only available 
with" "" { target c++14_down } }
+  return x + y;
+}
+
+int
+baz ()
+{
+  S a = {1, 2};
+  auto & [x, y] = a;   // { dg-warning "structured bindings only available 
with" "" { target c++14_down } }
+  return x + y;
+}
+
+int
+qux ()
+{
+  int a[2] = {1, 2};
+  auto & [x, y] = a;   // { dg-warning "structured bindings only available 
with" "" { target c++14_down } }
+  return x + y;
+}

Jakub


[PATCH][RFC] Fix CFG cleanup compile-time hog, PR85964

2018-05-29 Thread Richard Biener


The following fixes the situation where the initial sweep over the
CFG to remove trivially dead code regions causes excessive compile-time
because of using remove_edge_and_dominated_blocks and thus
iterate_fix_dominators.

The good thing is that I added cleanup_control_flow_pre doing this
initial sweep in PRE order.  So we can simply remove the entry edges
into the dead code regions and use the visited bitmap kept by the PRE
walk to remove unreachable blocks afterwards.

For dominators we then re-compute them from scratch which is way faster
for the testcase (a reduced one gets CFG cleanup time down from
19s to 0.16s).  The testcase still runs into a backwards jump-threading
scalability issue.

Note the patch will be slower for the case of not many removed edges
but it looks hard to find a good cut-off upfront.

Note we unfortunately cannot merge this with the unreachable block
removal because of the intermediate code to insert loop entry
forwarders which needs dominators to identify natural loop backedges.

Any opinions?

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

Thanks,
Richard.

diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 1bf7771dac1..4915d5e8f5f 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -57,7 +57,7 @@ bitmap cfgcleanup_altered_bbs;
 /* Remove any fallthru edge from EV.  Return true if an edge was removed.  */
 
 static bool
-remove_fallthru_edge (vec *ev)
+remove_fallthru_edge (vec *ev, bool only_edges_p)
 {
   edge_iterator ei;
   edge e;
@@ -68,7 +68,12 @@ remove_fallthru_edge (vec *ev)
if (e->flags & EDGE_COMPLEX)
  e->flags &= ~EDGE_FALLTHRU;
else
- remove_edge_and_dominated_blocks (e);
+ {
+   if (only_edges_p)
+ remove_edge (e);
+   else
+ remove_edge_and_dominated_blocks (e);
+ }
return true;
   }
   return false;
@@ -122,7 +127,8 @@ convert_single_case_switch (gswitch *swtch, 
gimple_stmt_iterator )
at block BB.  */
 
 static bool
-cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
+cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi,
+   bool only_edges_p)
 {
   edge taken_edge;
   bool retval = false;
@@ -182,7 +188,10 @@ cleanup_control_expr_graph (basic_block bb, 
gimple_stmt_iterator gsi)
}
 
  taken_edge->probability += e->probability;
- remove_edge_and_dominated_blocks (e);
+ if (only_edges_p)
+   remove_edge (e);
+ else
+   remove_edge_and_dominated_blocks (e);
  retval = true;
}
  else
@@ -222,7 +231,7 @@ cleanup_call_ctrl_altering_flag (gimple *bb_end)
true if anything changes.  */
 
 static bool
-cleanup_control_flow_bb (basic_block bb)
+cleanup_control_flow_bb (basic_block bb, bool only_edges_p)
 {
   gimple_stmt_iterator gsi;
   bool retval = false;
@@ -230,7 +239,27 @@ cleanup_control_flow_bb (basic_block bb)
 
   /* If the last statement of the block could throw and now cannot,
  we need to prune cfg.  */
-  retval |= gimple_purge_dead_eh_edges (bb);
+  if (only_edges_p)
+{
+  gimple *stmt = last_stmt (bb);
+  if (!(stmt && stmt_can_throw_internal (stmt)))
+   {
+ edge e;
+ edge_iterator ei;
+ for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
+   {
+ if (e->flags & EDGE_EH)
+   {
+ remove_edge (e);
+ retval = true;
+   }
+ else
+   ei_next ();
+   }
+   }
+}
+  else
+retval |= gimple_purge_dead_eh_edges (bb);
 
   gsi = gsi_last_nondebug_bb (bb);
   if (gsi_end_p (gsi))
@@ -245,7 +274,7 @@ cleanup_control_flow_bb (basic_block bb)
   || gimple_code (stmt) == GIMPLE_SWITCH)
 {
   gcc_checking_assert (gsi_stmt (gsi_last_bb (bb)) == stmt);
-  retval |= cleanup_control_expr_graph (bb, gsi);
+  retval |= cleanup_control_expr_graph (bb, gsi, only_edges_p);
 }
   else if (gimple_code (stmt) == GIMPLE_GOTO
   && TREE_CODE (gimple_goto_dest (stmt)) == ADDR_EXPR
@@ -270,7 +299,12 @@ cleanup_control_flow_bb (basic_block bb)
   for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
  if (e->dest != target_block)
-   remove_edge_and_dominated_blocks (e);
+   {
+ if (only_edges_p)
+   remove_edge (e);
+ else
+   remove_edge_and_dominated_blocks (e);
+   }
  else
{
  /* Turn off the EDGE_ABNORMAL flag.  */
@@ -300,7 +334,7 @@ cleanup_control_flow_bb (basic_block bb)
 now, they should be all unreachable anyway.  */
   for (gsi_next (); !gsi_end_p (gsi); )
gsi_remove (, true);
-  if (remove_fallthru_edge (bb->succs))
+  if (remove_fallthru_edge (bb->succs, only_edges_p))
retval = true;
   

Re: [C++ PATCH] Avoid bogus -Wunused-but-set* with structured binding (PR c++/85952)

2018-05-29 Thread Jason Merrill
On Tue, May 29, 2018 at 10:42 AM, Jakub Jelinek  wrote:
> On Tue, May 29, 2018 at 10:38:09AM -0400, Jason Merrill wrote:
>> >   int a[2] = {1, 2};
>> >   int D.2131[2] = a;
>> >   int x [value-expr: D.2131[0]];
>> >   int y [value-expr: D.2131[1]];
>> >
>> >   <>;
>> > int D.2131[2] = a;
>> >   return  = x + y;
>> >
>> > is what original dump shows as implemented, so I don't see a being used 
>> > here
>> > as an lvalue, we copy the elements into the temporary and that is all where
>> > it is referenced.
>>
>> Ah, no, you're right for foo, where the structured binding declaration
>> is not a reference.  And it looks like we shouldn't hit this path for
>>
>>   auto & [x,y] = a;
>>
>> but that should be added to the testcase.
>
> It is already there (in baz).

Well, yes, but in baz a is an S, not an array; I see value and
reference cases for S, but only value for int array.

Jason


Re: [C++ PATCH] Avoid bogus -Wunused-but-set* with structured binding (PR c++/85952)

2018-05-29 Thread Jakub Jelinek
On Tue, May 29, 2018 at 10:38:09AM -0400, Jason Merrill wrote:
> >   int a[2] = {1, 2};
> >   int D.2131[2] = a;
> >   int x [value-expr: D.2131[0]];
> >   int y [value-expr: D.2131[1]];
> >
> >   <>;
> > int D.2131[2] = a;
> >   return  = x + y;
> >
> > is what original dump shows as implemented, so I don't see a being used here
> > as an lvalue, we copy the elements into the temporary and that is all where
> > it is referenced.
> 
> Ah, no, you're right for foo, where the structured binding declaration
> is not a reference.  And it looks like we shouldn't hit this path for
> 
>   auto & [x,y] = a;
> 
> but that should be added to the testcase.

It is already there (in baz).

Jakub


Re: [PATCH][AArch64] Avoid paradoxical subregs for vector initialisation

2018-05-29 Thread Kyrill Tkachov

Hi Richard,

On 29/05/18 15:26, Richard Sandiford wrote:

Kyrill  Tkachov  writes:

Hi all,

The recent changes to aarch64_expand_vector_init cause an ICE in the
attached testcase.  The register allocator "ICEs with Max. number of
generated reload insns per insn is achieved (90)"

That is because aarch64_expand_vector_init creates a paradoxical subreg to move 
a DImode value
into a V2DI vector:
(insn 74 72 76 8 (set (reg:V2DI 287 [ _166 ])
  (subreg:V2DI (reg/v/f:DI 112 [ d ]) 0)) 1050 {*aarch64_simd_movv2di}

This is done because we want to express that the whole of the V2DI
vector will be written so that init-regs doesn't try to
zero-initialise it before we overwrite each lane individually anyway.

This can go bad for because if the DImode value is allocated in, say,
x30: the last register in that register class, the V2DI subreg of that
isn't valid or meaningful and that seems to cause the trouble.

It's kinda hard to know what the right solution for this is.
We could emit a duplicate of the value into all the lanes of the vector, but we 
have tests that test against that
(we're trying to avoid unnecessary duplicates)

What this patch does is it defines a pattern for moving a scalar into
lane 0 of a vector using a simple FMOV or LDR and represents that as a
merging with a vector of zeroes.  That way, the instruction represents
a full write of the destination vector but doesn't "read" more bits
from the source than necessary. The zeroing effect is also a more
accurate representation of the semantics of FMOV.

This feels like a hack.  Either the paradoxical subreg of the pseudo
is invalid for some reason (in which case we should ICE when it's formed,
not just in the case of x30 being allocated) or the subreg is valid,
in which case the RA should handle it correctly (and the backend should
give it the information it needs to do that).

I could see the argument for ignoring the problem for expediency if the
patch was a clean-up in its own right, but I think it's wrong to add so
much code to paper over a bug.


I see what you mean. Do you have any thoughts on where in RA we'd go about 
fixing this?
Since I don't know my way around RA I tried in the place I was most comfortable 
changing :)

In the meantime if adding this much code is not desirable to avoid this bug then
there is a more conservative "fix" of removing the maxv == 1 path from 
expand_vector_init
and emitting a duplicate of the first element to all the lanes of the vector 
followed by
a number of inserts.

Thanks,
Kyrill


Thanks,
Richard




Re: [C++ PATCH] Avoid bogus -Wunused-but-set* with structured binding (PR c++/85952)

2018-05-29 Thread Jason Merrill
On Tue, May 29, 2018 at 10:26 AM, Jakub Jelinek  wrote:
> On Tue, May 29, 2018 at 10:16:49AM -0400, Jason Merrill wrote:
>> On Tue, May 29, 2018, 4:31 AM Jakub Jelinek  wrote:
>> > Initializing the decomposition temporary from an expression with array type
>> > is a special aggregate initialization path in which we wouldn't mark the
>> > expression as read for the purposes of -Wunused-but-set*.
>> >
>> > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
>> > trunk?
>> >
>> > 2018-05-29  Jakub Jelinek  
>> >
>> > PR c++/85952
>> > * init.c (build_aggr_init): For structured binding initialized from
>> > array call mark_rvalue_use on the initializer.
>> >
>> > * g++.dg/warn/Wunused-var-33.C: New test.
>> >
>> > --- gcc/cp/init.c.jj2018-05-25 14:34:41.0 +0200
>> > +++ gcc/cp/init.c   2018-05-28 19:04:10.504063972 +0200
>> > @@ -1678,6 +1678,7 @@ build_aggr_init (tree exp, tree init, in
>> >if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
>> > {
>> >   from_array = 1;
>> > + init = mark_rvalue_use (init);
>>
>> This should be mark_lvalue_use, since the structured bindings refer to
>> the elements of the array rather than copying them.  OK with that
>> change.
>
> I think they refer to the elements of the decomposition variable (i.e. exp).
>
> "If the assignment-expression in the initializer has array type A and no
> ref-qualifier is present, e has type cv A and each element is 
> copy-initialized or direct-initialized from the
> corresponding element of the assignment-expression as specified by the form 
> of the
> initializer."
>
> is what applies in this case, and
>
>   int a[2] = {1, 2};
>   int D.2131[2] = a;
>   int x [value-expr: D.2131[0]];
>   int y [value-expr: D.2131[1]];
>
>   <>;
> int D.2131[2] = a;
>   return  = x + y;
>
> is what original dump shows as implemented, so I don't see a being used here
> as an lvalue, we copy the elements into the temporary and that is all where
> it is referenced.

Ah, no, you're right for foo, where the structured binding declaration
is not a reference.  And it looks like we shouldn't hit this path for

  auto & [x,y] = a;

but that should be added to the testcase.

Jason


Re: [PATCH] RISC-V: Add interrupt attribute support.

2018-05-29 Thread Nathan Sidwell

On 05/25/2018 06:30 PM, Jim Wilson wrote:


-/* Return true if func is a naked function.  */
+/* Return true if funcion TYPE is an interrupt function.  */

.^^^

+static bool
+riscv_interrupt_type_p (tree type)



funcion?


--
Nathan Sidwell


Re: [PATCH][AArch64] Avoid paradoxical subregs for vector initialisation

2018-05-29 Thread Richard Sandiford
Kyrill  Tkachov  writes:
> Hi all,
>
> The recent changes to aarch64_expand_vector_init cause an ICE in the
> attached testcase.  The register allocator "ICEs with Max. number of
> generated reload insns per insn is achieved (90)"
>
> That is because aarch64_expand_vector_init creates a paradoxical subreg to 
> move a DImode value
> into a V2DI vector:
> (insn 74 72 76 8 (set (reg:V2DI 287 [ _166 ])
>  (subreg:V2DI (reg/v/f:DI 112 [ d ]) 0)) 1050 {*aarch64_simd_movv2di}
>
> This is done because we want to express that the whole of the V2DI
> vector will be written so that init-regs doesn't try to
> zero-initialise it before we overwrite each lane individually anyway.
>
> This can go bad for because if the DImode value is allocated in, say,
> x30: the last register in that register class, the V2DI subreg of that
> isn't valid or meaningful and that seems to cause the trouble.
>
> It's kinda hard to know what the right solution for this is.
> We could emit a duplicate of the value into all the lanes of the vector, but 
> we have tests that test against that
> (we're trying to avoid unnecessary duplicates)
>
> What this patch does is it defines a pattern for moving a scalar into
> lane 0 of a vector using a simple FMOV or LDR and represents that as a
> merging with a vector of zeroes.  That way, the instruction represents
> a full write of the destination vector but doesn't "read" more bits
> from the source than necessary. The zeroing effect is also a more
> accurate representation of the semantics of FMOV.

This feels like a hack.  Either the paradoxical subreg of the pseudo
is invalid for some reason (in which case we should ICE when it's formed,
not just in the case of x30 being allocated) or the subreg is valid,
in which case the RA should handle it correctly (and the backend should
give it the information it needs to do that).

I could see the argument for ignoring the problem for expediency if the
patch was a clean-up in its own right, but I think it's wrong to add so
much code to paper over a bug.

Thanks,
Richard


Re: [C++ PATCH] Avoid bogus -Wunused-but-set* with structured binding (PR c++/85952)

2018-05-29 Thread Jakub Jelinek
On Tue, May 29, 2018 at 10:16:49AM -0400, Jason Merrill wrote:
> On Tue, May 29, 2018, 4:31 AM Jakub Jelinek  wrote:
> > Initializing the decomposition temporary from an expression with array type
> > is a special aggregate initialization path in which we wouldn't mark the
> > expression as read for the purposes of -Wunused-but-set*.
> >
> > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> > trunk?
> >
> > 2018-05-29  Jakub Jelinek  
> >
> > PR c++/85952
> > * init.c (build_aggr_init): For structured binding initialized from
> > array call mark_rvalue_use on the initializer.
> >
> > * g++.dg/warn/Wunused-var-33.C: New test.
> >
> > --- gcc/cp/init.c.jj2018-05-25 14:34:41.0 +0200
> > +++ gcc/cp/init.c   2018-05-28 19:04:10.504063972 +0200
> > @@ -1678,6 +1678,7 @@ build_aggr_init (tree exp, tree init, in
> >if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
> > {
> >   from_array = 1;
> > + init = mark_rvalue_use (init);
> 
> This should be mark_lvalue_use, since the structured bindings refer to
> the elements of the array rather than copying them.  OK with that
> change.

I think they refer to the elements of the decomposition variable (i.e. exp).

"If the assignment-expression in the initializer has array type A and no
ref-qualifier is present, e has type cv A and each element is copy-initialized 
or direct-initialized from the
corresponding element of the assignment-expression as specified by the form of 
the
initializer."

is what applies in this case, and

  int a[2] = {1, 2};
  int D.2131[2] = a;
  int x [value-expr: D.2131[0]];
  int y [value-expr: D.2131[1]];

  <>;
int D.2131[2] = a;
  return  = x + y;

is what original dump shows as implemented, so I don't see a being used here
as an lvalue, we copy the elements into the temporary and that is all where
it is referenced.

Jakub


Re: [C++ PATCH] Avoid bogus -Wunused-but-set* with structured binding (PR c++/85952)

2018-05-29 Thread Jason Merrill
On Tue, May 29, 2018, 4:31 AM Jakub Jelinek  wrote:
>
> Hi!
>
> Initializing the decomposition temporary from an expression with array type
> is a special aggregate initialization path in which we wouldn't mark the
> expression as read for the purposes of -Wunused-but-set*.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
>
> 2018-05-29  Jakub Jelinek  
>
> PR c++/85952
> * init.c (build_aggr_init): For structured binding initialized from
> array call mark_rvalue_use on the initializer.
>
> * g++.dg/warn/Wunused-var-33.C: New test.
>
> --- gcc/cp/init.c.jj2018-05-25 14:34:41.0 +0200
> +++ gcc/cp/init.c   2018-05-28 19:04:10.504063972 +0200
> @@ -1678,6 +1678,7 @@ build_aggr_init (tree exp, tree init, in
>if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
> {
>   from_array = 1;
> + init = mark_rvalue_use (init);

This should be mark_lvalue_use, since the structured bindings refer to
the elements of the array rather than copying them.  OK with that
change.

Jason


[PATCH][AArch64] Avoid paradoxical subregs for vector initialisation

2018-05-29 Thread Kyrill Tkachov

Hi all,

The recent changes to aarch64_expand_vector_init cause an ICE in the attached 
testcase.
The register allocator "ICEs with Max. number of generated reload insns per insn is 
achieved (90)"

That is because aarch64_expand_vector_init creates a paradoxical subreg to move 
a DImode value
into a V2DI vector:
(insn 74 72 76 8 (set (reg:V2DI 287 [ _166 ])
(subreg:V2DI (reg/v/f:DI 112 [ d ]) 0)) 1050 {*aarch64_simd_movv2di}

This is done because we want to express that the whole of the V2DI vector will 
be written
so that init-regs doesn't try to zero-initialise it before we overwrite each 
lane individually
anyway.

This can go bad for because if the DImode value is allocated in, say, x30: the 
last register
in that register class, the V2DI subreg of that isn't valid or meaningful and 
that seems to cause the trouble.

It's kinda hard to know what the right solution for this is.
We could emit a duplicate of the value into all the lanes of the vector, but we 
have tests that test against that
(we're trying to avoid unnecessary duplicates)

What this patch does is it defines a pattern for moving a scalar into lane 0 of 
a vector using a simple FMOV or LDR
and represents that as a merging with a vector of zeroes.
That way, the instruction represents a full write of the destination vector but doesn't 
"read" more bits from the source
than necessary. The zeroing effect is also a more accurate representation of 
the semantics of FMOV.

Bootstrapped and tested on aarch64-none-linux-gnu and tested also on 
aarch64_be-none-elf.

Ok for trunk?

Thanks,
Kyrill

2018-05-29  Kyrylo Tkachov  

* config/aarch64/aarch64-simd.md (aarch64_simd_vec_mov):
New define_insn.
* config/aarch64/aarch64.c (aarch64_get_aarch64_simd_vec_mov_code):
New function.
(aarch64_expand_vector_init): Avoid creating paradoxical subregs
of integer modes.

2018-05-29  Kyrylo Tkachov  

* c-c++-common/torture/aarch64-vect-init-1.c: New test.
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 9f4cb72f5c321136cfcc263bcb7c956365dbc512..292848984081e1fb517b85fc10816e50f5d0c841 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -808,6 +808,25 @@ (define_insn "aarch64_simd_vec_set"
   [(set_attr "type" "neon_ins, neon_from_gp, neon_load1_one_lane")]
 )
 
+
+;; Helper for aarch64_expand_vector_init.
+
+(define_insn "aarch64_simd_vec_mov"
+  [(set (match_operand:VALL_F16 0 "register_operand" "=w,w,w")
+	(vec_merge:VALL_F16
+	(vec_duplicate:VALL_F16
+		(match_operand: 1 "general_operand" "w,?r,m"))
+	(match_operand:VALL_F16 2 "aarch64_simd_imm_zero" )
+	(match_operand:SI 3 "immediate_operand")))]
+  "TARGET_SIMD
+   && ENDIAN_LANE_N (, exact_log2 (INTVAL (operands[3]))) == 0"
+  "@
+   fmov\\t%d0, %d1
+   fmov\\t%d0, %1
+   ldr\\t%0, %1"
+  [(set_attr "type" "fmov,f_mcr,neon_load1_1reg")]
+)
+
 (define_insn "*aarch64_simd_vec_copy_lane"
   [(set (match_operand:VALL_F16 0 "register_operand" "=w")
 	(vec_merge:VALL_F16
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b9759c638b010567f5047ff5129912986a30b49a..fdd8d2f587087180c71ce71003ec074dceeb6242 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -13879,6 +13879,44 @@ aarch64_simd_make_constant (rtx vals)
 return NULL_RTX;
 }
 
+/* Return the insn_code to use for MODE from the aarch64_simd_vec_mov
+   family of patterns.  */
+
+insn_code
+aarch64_get_aarch64_simd_vec_mov_code (machine_mode mode)
+{
+  switch (mode)
+{
+  case E_V8QImode:
+	return CODE_FOR_aarch64_simd_vec_movv8qi;
+  case E_V16QImode:
+	return CODE_FOR_aarch64_simd_vec_movv16qi;
+  case E_V4HImode:
+	return CODE_FOR_aarch64_simd_vec_movv4hi;
+  case E_V8HImode:
+	return CODE_FOR_aarch64_simd_vec_movv8hi;
+  case E_V2SImode:
+	return CODE_FOR_aarch64_simd_vec_movv2si;
+  case E_V4SImode:
+	return CODE_FOR_aarch64_simd_vec_movv4si;
+  case E_V2DImode:
+	return CODE_FOR_aarch64_simd_vec_movv2di;
+  case E_V4HFmode:
+	return CODE_FOR_aarch64_simd_vec_movv4hf;
+  case E_V8HFmode:
+	return CODE_FOR_aarch64_simd_vec_movv8hf;
+  case E_V2SFmode:
+	return CODE_FOR_aarch64_simd_vec_movv2sf;
+  case E_V4SFmode:
+	return CODE_FOR_aarch64_simd_vec_movv4sf;
+  case E_V2DFmode:
+	return CODE_FOR_aarch64_simd_vec_movv2df;
+  default:
+	gcc_unreachable ();
+}
+  return CODE_FOR_nothing;
+}
+
 /* Expand a vector initialisation sequence, such that TARGET is
initialised to contain VALS.  */
 
@@ -13967,7 +14005,7 @@ aarch64_expand_vector_init (rtx target, rtx vals)
 	 are equally useless to us, in which case just immediately set the
 	 vector register using the first element.  */
 
-  if (maxv == 1)
+  if (maxv == 1 && GET_MODE_NUNITS (mode).is_constant ())
 	{
 	  /* For vectors of two 64-bit elements, we can do even better.  */
 	  if (n_elts == 2
@@ -13999,12 +14037,24 @@ 

[PATCH] Simplify gcov_histogram as it's used only for ARCS counters.

2018-05-29 Thread Martin Liška
Hi.

As we use GCOV histogram just for ARCS type of counters, I would like
to simplify:

/* Cumulative counter data.  */
struct gcov_ctr_summary
{
  gcov_unsigned_t num;  /* number of counters.  */
  gcov_unsigned_t runs; /* number of program runs */
  gcov_type sum_all;/* sum of all counters accumulated.  */
  gcov_type run_max;/* maximum value on a single run.  */
  gcov_type sum_max;/* sum of individual run max values.  */
  gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; /* histogram of
  counter values.  */
};

 /* Object & program summary record.  */
 struct gcov_summary
 {
  gcov_unsigned_t checksum; /* checksum of program */
  struct gcov_ctr_summary ctrs[GCOV_COUNTERS_SUMMABLE];
 }


into:

 /* Object & program summary record.  */
 struct gcov_summary
 {
  gcov_unsigned_t checksum; /* Checksum of program.  */
  gcov_unsigned_t num;  /* Number of counters.  */
  gcov_unsigned_t runs; /* Number of program runs.  */
  gcov_type sum_all;/* Sum of all counters accumulated.  */
  gcov_type run_max;/* Maximum value on a single run.  */
  gcov_type sum_max;/* Sum of individual run max values.  */
  gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; /* Histogram of
  counter values.  */
 };

It improves code readability and I'm planning to come up with a new
gcov-tool compute_histogram which would be easier to implement.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Martin

gcc/ChangeLog:

2018-05-18  Martin Liska  

* auto-profile.c (read_autofdo_file): Do not use
gcov_ctr_summary struct.
(afdo_callsite_hot_enough_for_early_inline): Likewise.
* coverage.c (struct counts_entry): Likewise.
(read_counts_file): Read just single summary entry.
(get_coverage_counts): Use gcov_summary struct.
* coverage.h (get_coverage_counts): Likewise.
* gcov-dump.c (dump_working_sets): Likewise.
(tag_summary): Dump just single summary.
* gcov-io.c (gcov_write_summary): Write just histogram
summary.
(gcov_read_summary): Read just single summary.
(compute_working_sets): Use gcov_summary struct.
* gcov-io.h (GCOV_TAG_SUMMARY_LENGTH): Remove usage
of GCOV_COUNTERS_SUMMABLE.
(GCOV_COUNTERS_SUMMABLE): Remove.
(GCOV_FIRST_VALUE_COUNTER): Replace with
GCOV_COUNTER_V_INTERVAL.
(struct gcov_ctr_summary): Remove.
(struct gcov_summary): Directly use fields of former
gcov_ctr_summary.
(compute_working_sets): Use gcov_summary struct.
* gcov.c (read_count_file): Do not use ctrs fields.
* lto-cgraph.c (merge_profile_summaries): Use gcov_summary
struct.
* lto-streamer.h (struct GTY): Make profile_info gcov_summary
struct.
* profile.c: Likewise.
* profile.h: Likewise.

libgcc/ChangeLog:

2018-05-18  Martin Liska  

* libgcov-driver.c (gcov_compute_histogram): Remove usage
of gcov_ctr_summary.
(compute_summary): Do it just for a single summary.
(merge_one_data): Likewise.
(merge_summary): Simplify as we read just single summary.
(dump_one_gcov): Pass proper argument.
* libgcov-util.c (compute_one_gcov): Simplify as we have just
single summary.
(gcov_info_count_all_cold): Likewise.
(calculate_overlap): Likewise.
---
 gcc/auto-profile.c  |   9 +-
 gcc/coverage.c  |  49 ---
 gcc/coverage.h  |   2 +-
 gcc/gcov-dump.c |  63 +++---
 gcc/gcov-io.c   | 148 +++--
 gcc/gcov-io.h   |  38 -
 gcc/gcov.c  |   2 +-
 gcc/lto-cgraph.c|   4 +-
 gcc/lto-streamer.h  |   2 +-
 gcc/profile.c   |   2 +-
 gcc/profile.h   |   2 +-
 libgcc/libgcov-driver.c | 179 +++-
 libgcc/libgcov-util.c   |  90 +++-
 13 files changed, 236 insertions(+), 354 deletions(-)


diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
index e7944969ab0..197fa10e08c 100644
--- a/gcc/auto-profile.c
+++ b/gcc/auto-profile.c
@@ -318,8 +318,8 @@ static string_table *afdo_string_table;
 /* Store the AutoFDO source profile.  */
 static autofdo_source_profile *afdo_source_profile;
 
-/* gcov_ctr_summary structure to store the profile_info.  */
-static struct gcov_ctr_summary *afdo_profile_info;
+/* gcov_summary structure to store the profile_info.  */
+static gcov_summary *afdo_profile_info;
 
 /* Helper functions.  */
 
@@ -1682,8 +1682,7 @@ read_autofdo_file (void)
   if (auto_profile_file == NULL)
 auto_profile_file = DEFAULT_AUTO_PROFILE_FILE;
 
-  autofdo::afdo_profile_info = (struct gcov_ctr_summary *)xcalloc (
-  1, sizeof (struct 

Re: [PATCH] Support variables in expansion of -fprofile-generate option (PR gcov-profile/47618).

2018-05-29 Thread Martin Liška
On 05/29/2018 02:12 PM, Petr Špaček wrote:
> On 29.5.2018 14:03, Martin Liška wrote:
>> Hi.
>>
>> I'm sending V2, where I changed:
>>
>> - removed expansion of '%w', it's handled in: 
>> https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00729.html
>> - simplified concatenation in replace_filename_variables
>> - documentation for the expansion is added
>>
>> Ready for trunk?
> 
> It seems as step in the right direction. Thank you!
> 
> What's missing to address
> https://github.com/linux-test-project/lcov/issues/37
> completely?
> 

Well, I added support to print to stdout:
https://gcc.gnu.org/viewcvs/gcc?view=revision=260361

And GCC PR:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82702

mentioned in the lcov issue is also resolver.

Can you please specify what piece is missing for you?
Another way is to use gcov-tool to merge all the profiles (.gcda)
files created during parallel execution.

Martin


PING^1: [PATCH v2] C/C++: Add -Waddress-of-packed-member

2018-05-29 Thread H.J. Lu
On Fri, May 18, 2018 at 4:36 AM, H.J. Lu  wrote:
> On Thu, May 17, 2018 at 10:32:56AM -0700, H.J. Lu wrote:
>> On Mon, May 14, 2018 at 8:00 PM, Martin Sebor  wrote:
>> > On 05/14/2018 01:10 PM, H.J. Lu wrote:
>> >>
>> >> On Mon, May 14, 2018 at 10:40 AM, H.J. Lu  wrote:
>> >>
>> >> $ cat c.i
>> >> struct B { int i; };
>> >> struct C { struct B b; } __attribute__ ((packed));
>> >>
>> >> long* g8 (struct C *p) { return p; }
>> >> $ gcc -O2 -S c.i -Wno-incompatible-pointer-types
>> >> c.i: In function ‘g8’:
>> >> c.i:4:33: warning: taking value of packed 'struct C *' may result in
>> >> an
>> >> unaligned pointer value [-Waddress-of-packed-member]
>> 
>> 
>>   ^
>>  That should read "taking address" (not value) but...
>> >>>
>> >>>
>> >>> The value of 'struct C *' is an address. There is no address taken here.
>> >>>
>>  ...to help explain the problem I would suggest to mention the expected
>>  and actual alignment in the warning message.  E.g.,
>> 
>>    storing the address of a packed 'struct C' in 'struct C *' increases
>>  the
>>  alignment of the pointer from 1 to 4.
>> >>>
>> >>>
>> >>> I will take a look.
>> >>>
>>  (IIUC, the source type and destination type need not be the same so
>>  including both should be helpful in those cases.)
>> 
>>  Adding a note pointing to the declaration of either the struct or
>>  the member would help users find it if it's a header far removed
>>  from the point of use.
>> >>>
>> >>>
>> >>> I will see what I can do.
>> >>
>> >>
>> >> How about this
>> >>
>> >> [hjl@gnu-skx-1 pr51628]$ cat n9.i
>> >> struct B { int i; };
>> >> struct C { struct B b; } __attribute__ ((packed));
>> >>
>> >> long* g8 (struct C *p) { return p; }
>> >> [hjl@gnu-skx-1 pr51628]$
>> >> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>> >> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n9.i
>> >> n9.i: In function ‘g8’:
>> >> n9.i:4:33: warning: returning ‘struct C *’ from a function with
>> >> incompatible return type ‘long int *’ [-Wincompatible-pointer-types]
>> >>  long* g8 (struct C *p) { return p; }
>> >>  ^
>> >> n9.i:4:33: warning: taking value of packed ‘struct C *’ increases the
>> >> alignment of the pointer from 1 to 8 [-Waddress-of-packed-member]
>> >> n9.i:2:8: note: defined here
>> >>  struct C { struct B b; } __attribute__ ((packed));
>> >
>> >
>> > Mentioning the alignments looks good.
>> >
>> > I still find the "taking value" phrasing odd.  I think we would
>> > describe what's going on as "converting a pointer to a packed C
>> > to a pointer to C (with an alignment of 8)" so I'd suggest to
>> > use the term converting instead.
>>
>> How about this?
>>
>> [hjl@gnu-skx-1 pr51628]$ cat n12.i
>> struct B { int i; };
>> struct C { struct B b; } __attribute__ ((packed));
>>
>> struct B* g8 (struct C *p) { return p; }
>> [hjl@gnu-skx-1 pr51628]$ make n12.s
>> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n12.i
>> n12.i: In function ‘g8’:
>> n12.i:4:37: warning: returning ‘struct C *’ from a function with
>> incompatible return type ‘struct B *’ [-Wincompatible-pointer-types]
>>  struct B* g8 (struct C *p) { return p; }
>>  ^
>> n12.i:4:37: warning: converting a pointer to packed ‘struct C *’
>> increases the alignment of the pointer to ‘struct B *’ from 1 to 4
>> [-Waddress-of-packed-member]
>> n12.i:2:8: note: defined here
>>  struct C { struct B b; } __attribute__ ((packed));
>> ^
>> n12.i:1:8: note: defined here
>>  struct B { int i; };
>> ^
>> [hjl@gnu-skx-1 pr51628]$
>>
>> > I also think mentioning both the source and the destination types
>> > is useful irrespective of -Wincompatible-pointer-types because
>> > the latter is often suppressed using a cast, as in:
>> >
>> >   struct __attribute__ ((packed)) A { int i; };
>> >   struct B {
>> > struct A a;
>> >   } b;
>> >
>> >   long *p = (long*)   // -Waddress-of-packed-member
>> >   int *q = (int*)   // missing warning
>> >
>> > If the types above were obfuscated by macros, typedefs, or in
>> > C++ template parameters, it could be difficult to figure out
>> > what the type of the member is because neither it nor the name
>> > of the member appears in the message.
>>
>> How about this
>>
>> [hjl@gnu-skx-1 pr51628]$ cat n13.i
>> struct __attribute__ ((packed)) A { int i; };
>> struct B {
>>   struct A a;
>> } b;
>>
>> long *p = (long*)
>> int *q = (int*)
>> [hjl@gnu-skx-1 pr51628]$ make n13.s
>> /export/build/gnu/gcc-test/build-x86_64-linux/gcc/xgcc
>> -B/export/build/gnu/gcc-test/build-x86_64-linux/gcc/ -O2 -S n13.i
>> n13.i:6:18: warning: taking address of packed member of ‘struct A’ may
>> result in an unaligned pointer value [-Waddress-of-packed-member]
>>  long *p = (long*)
>>   ^~
>> 

Re: [PATCH] Support variables in expansion of -fprofile-generate option (PR gcov-profile/47618).

2018-05-29 Thread Petr Špaček

On 29.5.2018 14:03, Martin Liška wrote:

Hi.

I'm sending V2, where I changed:

- removed expansion of '%w', it's handled in: 
https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00729.html
- simplified concatenation in replace_filename_variables
- documentation for the expansion is added

Ready for trunk?


It seems as step in the right direction. Thank you!

What's missing to address
https://github.com/linux-test-project/lcov/issues/37
completely?

--
Petr Špaček  @  CZ.NIC


Re: [PATCH] Support variables in expansion of -fprofile-generate option (PR gcov-profile/47618).

2018-05-29 Thread Martin Liška
Hi.

I'm sending V2, where I changed:

- removed expansion of '%w', it's handled in: 
https://gcc.gnu.org/ml/gcc-patches/2018-05/msg00729.html
- simplified concatenation in replace_filename_variables
- documentation for the expansion is added

Ready for trunk?

Martin
>From ac35fffa250685ec9f5fd04c1076558769848f38 Mon Sep 17 00:00:00 2001
From: marxin 
Date: Fri, 18 May 2018 13:12:06 +0200
Subject: [PATCH] Support variables in expansion of -fprofile-generate option
 (PR gcov-profile/47618).

gcc/ChangeLog:

2018-05-29  Martin Liska  

	PR gcov-profile/47618
	* doc/invoke.texi: Document how -fprofile-dir format
is extended.

libgcc/ChangeLog:

2018-05-29  Martin Liska  

	PR gcov-profile/47618
	* libgcov-driver-system.c (replace_filename_variables): New
function.
	(gcov_exit_open_gcda_file): Use it.
---
 gcc/doc/invoke.texi| 14 +++
 libgcc/libgcov-driver-system.c | 70 ++
 2 files changed, 84 insertions(+)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 65f32d67640..42ab7e9211a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -11294,6 +11294,20 @@ and its related options.  Both absolute and relative paths can be used.
 By default, GCC uses the current directory as @var{path}, thus the
 profile data file appears in the same directory as the object file.
 
+When an executable is run in a massive parallel environment, it is recommended
+to save profile to different folders.  That can be done with variables
+in @var{path} that are exported during run-time:
+
+@table @gcctabopt
+
+@item %p
+process ID.
+
+@item %q@{VAR@}
+value of environment variable @var{VAR}
+
+@end table
+
 @item -fprofile-generate
 @itemx -fprofile-generate=@var{path}
 @opindex fprofile-generate
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 0df44239363..1216edb1a50 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -128,6 +128,74 @@ create_file_directory (char *filename)
 #endif
 }
 
+/* Replace filename variables in FILENAME.  We currently support expansion:
+
+   %p - process ID
+   %q{ENV} - value of environment variable ENV
+   */
+
+static char *
+replace_filename_variables (char *filename)
+{
+  char buffer[16];
+  char empty[] = "";
+  for (char *p = filename; *p != '\0'; p++)
+{
+  unsigned length = strlen (filename);
+  if (*p == '%' && *(p + 1) != '\0')
+	{
+	  unsigned start = p - filename;
+	  p++;
+	  char *replacement = NULL;
+	  switch (*p)
+	{
+	case 'p':
+	  sprintf (buffer, "%d", getpid ());
+	  replacement = buffer;
+	  p++;
+	  break;
+	case 'q':
+	  if (*(p + 1) == '{')
+		{
+		  p += 2;
+		  char *e = strchr (p, '}');
+		  if (e)
+		{
+		  *e = '\0';
+		  replacement = getenv (p);
+		  if (replacement == NULL)
+			replacement = empty;
+		  p = e + 1;
+		}
+		  else
+		return filename;
+		}
+	  break;
+	default:
+	  return filename;
+	}
+
+	  /* Concat beginning of the path, replacement and
+	 ending of the path.  */
+	  unsigned end = length - (p - filename);
+	  unsigned repl_length = strlen (replacement);
+
+	  char *buffer = (char *)xmalloc (start + end + repl_length + 1);
+	  char *buffer_ptr = buffer;
+	  buffer_ptr = (char *)mempcpy (buffer_ptr, filename, start);
+	  buffer_ptr = (char *)mempcpy (buffer_ptr, replacement, repl_length);
+	  buffer_ptr = (char *)mempcpy (buffer_ptr, p, end);
+	  *buffer_ptr = '\0';
+
+	  free (filename);
+	  filename = buffer;
+	  p = buffer + start + repl_length;
+	}
+}
+
+  return filename;
+}
+
 static void
 allocate_filename_struct (struct gcov_filename *gf)
 {
@@ -216,6 +284,8 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 }
   strcpy (dst, fname);
 
+  gf->filename = replace_filename_variables (gf->filename);
+
   if (!gcov_open (gf->filename))
 {
   /* Open failed likely due to missed directory.
-- 
2.17.0



[PATCH] Fix get_earlier_stmt call

2018-05-29 Thread Richard Biener


This fixes the get_earlier_stmt call in vect_preserves_scalar_order_p to
properly use non-pattern stmts.  I came along this when reworking
how we change DR_STMT during vectorization - this mimics the way
the SLP code uses get_later_stmt.

I've added asserts into get_earlier/later_stmt to make sure we're never
called on pattern stmts (those can end up with UIDs out-of-order).

Not sure if we actually run into this (not in the testsuite),
but it'll be a separate rev to bisect to and backport if required.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

>From 823c9b42d8910c78413e087acf3bb5546b04b300 Mon Sep 17 00:00:00 2001
From: Richard Guenther 
Date: Tue, 29 May 2018 13:44:18 +0200
Subject: [PATCH] fix-dr-order-checks

* tree-vect-data-refs.c (vect_preserves_scalar_order_p): Make
sure to use non-pattern stmts for get_earlier_stmt arguments.
* tree-vectorizer.h (get_earlier_stmt): Assert we do not get
called on pattern stmts.
(get_later_stmt): Likewise.

diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index f46eb467da6..9255c53189d 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -212,6 +212,10 @@ vect_preserves_scalar_order_p (gimple *stmt_a, gimple 
*stmt_b)
  (but could happen later) while reads will happen no later than their
  current position (but could happen earlier).  Reordering is therefore
  only possible if the first access is a write.  */
+  if (is_pattern_stmt_p (stmtinfo_a))
+stmt_a = STMT_VINFO_RELATED_STMT (stmtinfo_a);
+  if (is_pattern_stmt_p (stmtinfo_b))
+stmt_b = STMT_VINFO_RELATED_STMT (stmtinfo_b);
   gimple *earlier_stmt = get_earlier_stmt (stmt_a, stmt_b);
   return !DR_IS_WRITE (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt)));
 }
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index f7646349b65..25d0aae8eaa 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1068,8 +1068,12 @@ get_earlier_stmt (gimple *stmt1, gimple *stmt2)
   if (uid1 == 0 || uid2 == 0)
 return NULL;
 
-  gcc_checking_assert (uid1 <= stmt_vec_info_vec->length ()
-  && uid2 <= stmt_vec_info_vec->length ());
+  gcc_assert (uid1 <= stmt_vec_info_vec->length ()
+ && uid2 <= stmt_vec_info_vec->length ());
+  gcc_checking_assert ((STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt1))
+   || !STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt1)))
+  && (STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt2))
+  || !STMT_VINFO_RELATED_STMT (vinfo_for_stmt 
(stmt2;
 
   if (uid1 < uid2)
 return stmt1;
@@ -1096,8 +1100,12 @@ get_later_stmt (gimple *stmt1, gimple *stmt2)
   if (uid1 == 0 || uid2 == 0)
 return NULL;
 
-  gcc_assert (uid1 <= stmt_vec_info_vec->length ());
-  gcc_assert (uid2 <= stmt_vec_info_vec->length ());
+  gcc_assert (uid1 <= stmt_vec_info_vec->length ()
+ && uid2 <= stmt_vec_info_vec->length ());
+  gcc_checking_assert ((STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt1))
+   || !STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt1)))
+  && (STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt2))
+  || !STMT_VINFO_RELATED_STMT (vinfo_for_stmt 
(stmt2;
 
   if (uid1 > uid2)
 return stmt1;


[PATCH] Move stmt_vec_info_vec into vec_info class

2018-05-29 Thread Richard Biener


This is another baby-step towards re-using vectorizer analysis
after doing many, comparing costs and then deciding on one.

It should allow to "simply" re-instantiate the stmt_vec_info_vec
vector before calling vect_transform_*.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2018-05-29  Richard Biener  

* tree-vectorizer.h (struct vec_info): Add stmt_vec_infos
member.
(stmt_vec_info_vec): Make pointer.
(init_stmt_vec_info_vec): Remove.
(free_stmt_vec_info_vec): Likewise.
(set_stmt_vec_info_vec): New function.
(free_stmt_vec_infos): Likewise.
(vinfo_for_stmt): Adjust for stmt_vec_info_vec indirection.
(set_vinfo_for_stmt): Likewise.
(get_earlier_stmt): Likewise.
(get_later_stmt): Likewise.
* tree-vectorizer.c (stmt_vec_info_vec): Make pointer.
(vec_info::vec_info): Allocate stmt_vec_infos and set the global.
(vec_info::~vec_info): Free stmt_vec_infos.
(vectorize_loops): Set the global stmt_vec_info_vec to NULL.
Remove old init_stmt_vec_info_vec/free_stmt_vec_info_vec calls.
(pass_slp_vectorize::execute): Likewise.
* tree-vect-stmts.c (init_stmt_vec_info_vec): Remove.
(free_stmt_vec_info_vec): Likewise.
(set_stmt_vec_info_vec): New function.
(free_stmt_vec_infos): Likewise.
* tree-vect-loop.c (_loop_vec_info::~_loop_vec_info): Set
the global stmt_vec_info_vec.
* tree-parloops.c (gather_scalar_reductions): Use
set_stmt_vec_info_vec/free_stmt_vec_infos and maintain a local
vector.

diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 3a788ccf1b7..aa74427296e 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -2593,8 +2593,9 @@ gather_scalar_reductions (loop_p loop, 
reduction_info_table_type *reduction_list
   auto_vec double_reduc_phis;
   auto_vec double_reduc_stmts;
 
-  if (!stmt_vec_info_vec.exists ())
-init_stmt_vec_info_vec ();
+  vec stmt_vec_infos;
+  stmt_vec_infos.create (50);
+  set_stmt_vec_info_vec (_vec_infos);
 
   simple_loop_info = vect_analyze_loop_form (loop);
   if (simple_loop_info == NULL)
@@ -2674,7 +2675,7 @@ gather_scalar_reductions (loop_p loop, 
reduction_info_table_type *reduction_list
 
  gather_done:
   /* Release the claim on gimple_uid.  */
-  free_stmt_vec_info_vec ();
+  free_stmt_vec_infos (_vec_infos);
 
   if (reduction_list->elements () == 0)
 return;
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index c49e1c55102..9424b52a99b 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -894,6 +894,8 @@ _loop_vec_info::~_loop_vec_info ()
   gimple_stmt_iterator si;
   int j;
 
+  /* ???  We're releasing loop_vinfos en-block.  */
+  set_stmt_vec_info_vec (_vec_infos);
   nbbs = loop->num_nodes;
   for (j = 0; j < nbbs; j++)
 {
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 66c78de8e2a..759ea23b6f2 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -9862,28 +9862,27 @@ new_stmt_vec_info (gimple *stmt, vec_info *vinfo)
 }
 
 
-/* Create a hash table for stmt_vec_info. */
+/* Set the current stmt_vec_info vector to V.  */
 
 void
-init_stmt_vec_info_vec (void)
+set_stmt_vec_info_vec (vec *v)
 {
-  gcc_assert (!stmt_vec_info_vec.exists ());
-  stmt_vec_info_vec.create (50);
+  stmt_vec_info_vec = v;
 }
 
-
-/* Free hash table for stmt_vec_info. */
+/* Free the stmt_vec_info entries in V and release V.  */
 
 void
-free_stmt_vec_info_vec (void)
+free_stmt_vec_infos (vec *v)
 {
   unsigned int i;
   stmt_vec_info info;
-  FOR_EACH_VEC_ELT (stmt_vec_info_vec, i, info)
+  FOR_EACH_VEC_ELT (*v, i, info)
 if (info != NULL)
   free_stmt_vec_info (STMT_VINFO_STMT (info));
-  gcc_assert (stmt_vec_info_vec.exists ());
-  stmt_vec_info_vec.release ();
+  if (v == stmt_vec_info_vec)
+stmt_vec_info_vec = NULL;
+  v->release ();
 }
 
 
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 86cd025fe73..8ff90b37ee6 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -85,7 +85,7 @@ along with GCC; see the file COPYING3.  If not see
 source_location vect_location;
 
 /* Vector mapping GIMPLE stmt to stmt_vec_info. */
-vec stmt_vec_info_vec;
+vec *stmt_vec_info_vec;
 
 /* Dump a cost entry according to args to F.  */
 
@@ -456,6 +456,8 @@ vec_info::vec_info (vec_info::vec_kind kind_in, void 
*target_cost_data_in)
 ddrs (vNULL),
 target_cost_data (target_cost_data_in)
 {
+  stmt_vec_infos.create (50);
+  set_stmt_vec_info_vec (_vec_infos);
 }
 
 vec_info::~vec_info ()
@@ -477,6 +479,7 @@ vec_info::~vec_info ()
   free_data_refs (datarefs);
   free_dependence_relations (ddrs);
   destroy_cost_data (target_cost_data);
+  free_stmt_vec_infos (_vec_infos);
 }
 
 /* A helper function to free scev and LOOP niter information, as well as
@@ -682,7 +685,7 @@ vectorize_loops (void)
   if (cfun->has_simduid_loops)
 note_simd_array_uses 

[PATCH] Account iterate_fix_dominators to TV_DOMINANCE

2018-05-29 Thread Richard Biener


Boostrapped on x86_64-unknown-linux-gnu, applied.

Richard.

2018-05-29  Richard Biener  

* dominance.c (iterate_fix_dominators): Push/pop TV_DOMINANCE.

diff --git a/gcc/dominance.c b/gcc/dominance.c
index 20671983f98..5ba765c82be 100644
--- a/gcc/dominance.c
+++ b/gcc/dominance.c
@@ -1475,6 +1475,8 @@ iterate_fix_dominators (enum cdi_direction dir, 
vec bbs,
   return;
 }
 
+  timevar_push (TV_DOMINANCE);
+
   /* Construct the graph G.  */
   hash_map map (251);
   FOR_EACH_VEC_ELT (bbs, i, bb)
@@ -1537,6 +1539,8 @@ iterate_fix_dominators (enum cdi_direction dir, 
vec bbs,
   free (parent);
 
   free_graph (g);
+
+  timevar_pop (TV_DOMINANCE);
 }
 
 void


Re: [PATCH] libgcov: report about a different timestamp (PR gcov-profile/85759).

2018-05-29 Thread Nathan Sidwell

On 05/29/2018 05:32 AM, Martin Liška wrote:

Hi.

As showed twice in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85759 it's 
quite problematic
when a profile data file is overwritten for a different compilation unit. I 
believe it's not
intentional in most cases and it deserves an error message in libgcov. 
Moreover, to be really
sure we don't break a profile, users should use GCOV_EXIT_AT_ERROR.

Tested on gcov.exp on x86_64-linux-gnu.

Ready to install after proper bootstrap?



ok, thanks


--
Nathan Sidwell


[AARCH64] Add support of ARMv8.4 in saphira for Qualcomm server part

2018-05-29 Thread Sameera Deshpande
Hi!

Please find attached the patch to add support of ARMv8.4 in saphira
for Qualcomm server part. Tested on aarch64, without any regressions.

Ok for trunk?

-- 
- Thanks and regards,
  Sameera D.
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index 33b96ca2861..e64d8314fa9 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -86,10 +86,10 @@ AARCH64_CORE("thunderx2t99",  thunderx2t99,  thunderx2t99, 8_1A,  AARCH64_FL_FOR
 AARCH64_CORE("cortex-a55",  cortexa55, cortexa53, 8_2A,  AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa53, 0x41, 0xd05, -1)
 AARCH64_CORE("cortex-a75",  cortexa75, cortexa57, 8_2A,  AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa73, 0x41, 0xd0a, -1)
 
-/* ARMv8.3-A Architecture Processors.  */
+/* ARMv8.4-A Architecture Processors.  */
 
 /* Qualcomm ('Q') cores. */
-AARCH64_CORE("saphira", saphira,falkor,8_3A,  AARCH64_FL_FOR_ARCH8_3 | AARCH64_FL_CRYPTO | AARCH64_FL_RCPC, saphira,   0x51, 0xC01, -1)
+AARCH64_CORE("saphira", saphira,falkor,8_4A,  AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_CRYPTO | AARCH64_FL_RCPC, saphira,   0x51, 0xC01, -1)
 
 /* ARMv8-A big.LITTLE implementations.  */
 


Re: [PATCH] Introduce VEC_UNPACK_FIX_TRUNC_{LO,HI}_EXPR and VEC_PACK_FLOAT_EXPR, use it in x86 vectorization (PR target/85918)

2018-05-29 Thread Richard Biener
On Tue, 29 May 2018, Jakub Jelinek wrote:

> On Tue, May 29, 2018 at 11:15:51AM +0200, Richard Biener wrote:
> > Looking at other examples the only thing we have is
> > maybe_ne and friends on TYPE_VECTOR_SUBPARTS.  But I think the only
> > thing missing is
> > 
> >  || (maybe_ne (TYPE_VECTOR_SUBPARTS (lhs_type),
> >2 * TYPE_VECTOR_SUBPARTS (rhs_type)))
> > 
> > that together with the mode size check should ensure same size
> > vectors.
> 
> The other way around.  It would then be (and I've added similar tests for
> VEC_PACK*):

Ah, of course...

OK if it tests ok.

Thanks,
Richard.

> 2018-05-29  Jakub Jelinek  
> 
>   * tree-cfg.c (verify_gimple_assign_unary): Add checking for
>   VEC_UNPACK_*_EXPR.
>   (verify_gimple_assign_binary): Check TYPE_VECTOR_SUBPARTS for
>   VEC_PACK_*_EXPR.
> 
> --- gcc/tree-cfg.c.jj 2018-05-28 19:47:55.180685259 +0200
> +++ gcc/tree-cfg.c2018-05-29 11:27:14.521339290 +0200
> @@ -3678,7 +3678,37 @@ verify_gimple_assign_unary (gassign *stm
>  case VEC_UNPACK_FLOAT_LO_EXPR:
>  case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
>  case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
> -  /* FIXME.  */
> +  if (TREE_CODE (rhs1_type) != VECTOR_TYPE
> +  || TREE_CODE (lhs_type) != VECTOR_TYPE
> +  || (!INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
> +   && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type)))
> +  || (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
> +   && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type)))
> +   || ((rhs_code == VEC_UNPACK_HI_EXPR
> +|| rhs_code == VEC_UNPACK_LO_EXPR)
> +   && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
> +   != INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type
> +   || ((rhs_code == VEC_UNPACK_FLOAT_HI_EXPR
> +|| rhs_code == VEC_UNPACK_FLOAT_LO_EXPR)
> +   && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
> +   || SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type
> +   || ((rhs_code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
> +|| rhs_code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
> +   && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
> +   || SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type
> +   || (maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
> + 2 * GET_MODE_SIZE (element_mode (rhs1_type)))
> +   && (!VECTOR_BOOLEAN_TYPE_P (lhs_type)
> +   || !VECTOR_BOOLEAN_TYPE_P (rhs1_type)))
> +   || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (lhs_type),
> +TYPE_VECTOR_SUBPARTS (rhs1_type)))
> + {
> +   error ("type mismatch in vector unpack expression");
> +   debug_generic_expr (lhs_type);
> +   debug_generic_expr (rhs1_type);
> +   return true;
> +}
> +
>return false;
>  
>  case NEGATE_EXPR:
> @@ -3993,7 +4023,9 @@ verify_gimple_assign_binary (gassign *st
>== INTEGRAL_TYPE_P (TREE_TYPE (lhs_type
>   || !types_compatible_p (rhs1_type, rhs2_type)
>   || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
> -  2 * GET_MODE_SIZE (element_mode (lhs_type
> +  2 * GET_MODE_SIZE (element_mode (lhs_type)))
> + || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
> +  TYPE_VECTOR_SUBPARTS (lhs_type)))
>{
>  error ("type mismatch in vector pack expression");
>  debug_generic_expr (lhs_type);
> @@ -4012,7 +4044,9 @@ verify_gimple_assign_binary (gassign *st
> || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))
> || !types_compatible_p (rhs1_type, rhs2_type)
> || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
> -2 * GET_MODE_SIZE (element_mode (lhs_type
> +2 * GET_MODE_SIZE (element_mode (lhs_type)))
> +   || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
> +TYPE_VECTOR_SUBPARTS (lhs_type)))
>   {
> error ("type mismatch in vector pack expression");
> debug_generic_expr (lhs_type);
> 
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)


[Ada] Adjust documentation of -gnatn switch

2018-05-29 Thread Pierre-Marie de Rodat
This changes the wording in the documentation of the -gnatn switch to make
it use "units" rather than "modules" and also adjusts the usage message.

No functional changes.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Eric Botcazou  

gcc/ada/

* doc/gnat_ugn/building_executable_programs_with_gnat.rst (Alphabetical
List of All Switches): Replace "modules" with "units".
(Subprogram Inlining Control): Likewise.
* gnat_ugn.texi: Regenerate.
* usage.adb (Usage): Fix description of -gnatn switch.--- gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -1255,7 +1255,7 @@ Alphabetical List of All Switches
   of the program, instead of a fragmentary view with the usual approach.
   This can also speed up the compilation of big programs and reduce the
   size of the executable, compared with a traditional per-unit compilation
-  with inlining across modules enabled by the :switch:`-gnatn` switch.
+  with inlining across units enabled by the :switch:`-gnatn` switch.
   The drawback of this approach is that it may require more memory and that
   the debugging information generated by -g with it might be hardly usable.
   The switch, as well as the accompanying :switch:`-Ox` switches, must be
@@ -1910,10 +1910,10 @@ Alphabetical List of All Switches
 .. index:: -gnatn  (gcc)
 
 :switch:`-gnatn[12]`
-  Activate inlining across modules for subprograms for which pragma ``Inline``
+  Activate inlining across units for subprograms for which pragma ``Inline``
   is specified. This inlining is performed by the GCC back-end. An optional
-  digit sets the inlining level: 1 for moderate inlining across modules
-  or 2 for full inlining across modules. If no inlining level is specified,
+  digit sets the inlining level: 1 for moderate inlining across units
+  or 2 for full inlining across units. If no inlining level is specified,
   the compiler will pick it based on the optimization level.
 
 
@@ -5512,17 +5512,17 @@ Subprogram Inlining Control
   The ``n`` here is intended to suggest the first syllable of the word 'inline'.
   GNAT recognizes and processes ``Inline`` pragmas. However, for inlining to
   actually occur, optimization must be enabled and, by default, inlining of
-  subprograms across modules is not performed. If you want to additionally
-  enable inlining of subprograms specified by pragma ``Inline`` across modules,
+  subprograms across units is not performed. If you want to additionally
+  enable inlining of subprograms specified by pragma ``Inline`` across units,
   you must also specify this switch.
 
-  In the absence of this switch, GNAT does not attempt inlining across modules
+  In the absence of this switch, GNAT does not attempt inlining across units
   and does not access the bodies of subprograms for which ``pragma Inline`` is
   specified if they are not in the current unit.
 
   You can optionally specify the inlining level: 1 for moderate inlining across
-  modules, which is a good compromise between compilation times and performances
-  at run time, or 2 for full inlining across modules, which may bring about
+  units, which is a good compromise between compilation times and performances
+  at run time, or 2 for full inlining across units, which may bring about
   longer compilation times. If no inlining level is specified, the compiler will
   pick it based on the optimization level: 1 for :switch:`-O1`, :switch:`-O2` or
   :switch:`-Os` and 2 for :switch:`-O3`.

--- gcc/ada/gnat_ugn.texi
+++ gcc/ada/gnat_ugn.texi
@@ -8831,7 +8831,7 @@ the best interprocedural optimization strategy based on a complete view
 of the program, instead of a fragmentary view with the usual approach.
 This can also speed up the compilation of big programs and reduce the
 size of the executable, compared with a traditional per-unit compilation
-with inlining across modules enabled by the @code{-gnatn} switch.
+with inlining across units enabled by the @code{-gnatn} switch.
 The drawback of this approach is that it may require more memory and that
 the debugging information generated by -g with it might be hardly usable.
 The switch, as well as the accompanying @code{-Ox} switches, must be
@@ -9716,10 +9716,10 @@ means that no limit applies.
 
 @item @code{-gnatn[12]}
 
-Activate inlining across modules for subprograms for which pragma @code{Inline}
+Activate inlining across units for subprograms for which pragma @code{Inline}
 is specified. This inlining is performed by the GCC back-end. An optional
-digit sets the inlining level: 1 for moderate inlining across modules
-or 2 for full inlining across modules. If no inlining level is specified,
+digit sets the inlining level: 1 for moderate inlining across units
+or 2 for full inlining across units. If no inlining level is specified,
 the compiler will pick it based on the optimization level.
 @end table
 
@@ -14657,17 +14657,17 @@ 

[Ada] Wrong equality on untagged private type

2018-05-29 Thread Pierre-Marie de Rodat
When a private type declaration T1 is completed with a derivation of an
untagged private type that overrides the predefined equality primitive, and the
full view of T2 is a derivation of another private type T2 whose full view is a
tagged type, the compiler may generate code that references the wrong equality
primitive when processing comparisons of objects of type T1.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Javier Miranda  

gcc/ada/

* exp_ch4.adb (Expand_N_Op_Eq, Expand_Composite_Equality): Use the new
subprogram Inherits_From_Tagged_Full_View to identify more reliably
untagged private types completed with a derivation of an untagged
private whose full view is a tagged type.
* sem_util.ads, sem_util.adb (Inherits_From_Tagged_Full_View): New
subprogram.
(Collect_Primitive_Operations): Handle untagged private types completed
with a derivation of an untagged private type whose full view is a
tagged type. In such case, collecting the list of primitives we may
find two equality primitives: one associated with the untagged private
and another associated with the ultimate tagged type (and we must
remove from the returned list this latter one).

gcc/testsuite/

* gnat.dg/equal2.adb: New testcase.--- gcc/ada/exp_ch4.adb
+++ gcc/ada/exp_ch4.adb
@@ -2488,17 +2488,13 @@ package body Exp_Ch4 is
 Full_Type := Root_Type (Full_Type);
  end if;
 
- --  If this is derived from an untagged private type completed with a
- --  tagged type, it does not have a full view, so we use the primitive
- --  operations of the private type. This check should no longer be
- --  necessary when these types receive their full views ???
-
- if Is_Private_Type (Typ)
-   and then not Is_Tagged_Type (Typ)
-   and then not Is_Controlled (Typ)
-   and then Is_Derived_Type (Typ)
-   and then No (Full_View (Typ))
- then
+ --  If this is an untagged private type completed with a derivation of
+ --  an untagged private type whose full view is a tagged type, we use
+ --  the primitive operations of the private parent type (since it does
+ --  not have a full view, and also because its equality primitive may
+ --  have been overridden in its untagged full view).
+
+ if Inherits_From_Tagged_Full_View (Typ) then
 Prim := First_Elmt (Collect_Primitive_Operations (Typ));
  else
 Prim := First_Elmt (Primitive_Operations (Full_Type));
@@ -7857,16 +7853,14 @@ package body Exp_Ch4 is
return;
 end if;
 
---  If this is derived from an untagged private type completed with
---  a tagged type, it does not have a full view, so we use the
---  primitive operations of the private type. This check should no
---  longer be necessary when these types get their full views???
+--  If this is an untagged private type completed with a derivation
+--  of an untagged private type whose full view is a tagged type,
+--  we use the primitive operations of the private type (since it
+--  does not have a full view, and also because its equality
+--  primitive may have been overridden in its untagged full view).
+
+if Inherits_From_Tagged_Full_View (A_Typ) then
 
-if Is_Private_Type (A_Typ)
-  and then not Is_Tagged_Type (A_Typ)
-  and then Is_Derived_Type (A_Typ)
-  and then No (Full_View (A_Typ))
-then
--  Search for equality operation, checking that the operands
--  have the same type. Note that we must find a matching entry,
--  or something is very wrong.

--- gcc/ada/sem_util.adb
+++ gcc/ada/sem_util.adb
@@ -5084,15 +5084,7 @@ package body Sem_Util is
--
 
function Collect_Primitive_Operations (T : Entity_Id) return Elist_Id is
-  B_Type : constant Entity_Id := Base_Type (T);
-  B_Decl : constant Node_Id   := Original_Node (Parent (B_Type));
-  B_Scope: Entity_Id  := Scope (B_Type);
-  Op_List: Elist_Id;
-  Formal : Entity_Id;
-  Is_Prim: Boolean;
-  Is_Type_In_Pkg : Boolean;
-  Formal_Derived : Boolean := False;
-  Id : Entity_Id;
+  B_Type : constant Entity_Id := Base_Type (T);
 
   function Match (E : Entity_Id) return Boolean;
   --  True if E's base type is B_Type, or E is of an anonymous access type
@@ -5120,6 +5112,18 @@ package body Sem_Util is
and then Full_View (Etyp) = B_Type);
   end Match;
 
+  --  Local variables
+
+  B_Decl : constant Node_Id := Original_Node (Parent (B_Type));
+  B_Scope: Entity_Id   

[Ada] Improper behavior of floating-point attributes

2018-05-29 Thread Pierre-Marie de Rodat
This patch fixes an error in the handling of attributes Pred and Succ when
applied to the limit values of a floating-point type. The RM mandates that
such operations must raise constraint_error, but GNAT generated in most cases
an infinite value, regardless of whether overflow checks were enabled.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Ed Schonberg  

gcc/ada/

* libgnat/s-fatgen.adb (Succ, Pred):  Raise Constraint_Error
unconditionally when applied to the largest positive (resp. largest
negative) value of a floating-point type.

gcc/testsuite/

* gnat.dg/float_attributes_overflows.adb: New testcase.
--- gcc/ada/libgnat/s-fatgen.adb
+++ gcc/ada/libgnat/s-fatgen.adb
@@ -415,16 +415,7 @@ package body System.Fat_Gen is
 
   elsif X = T'First then
 
- --  If not generating infinities, we raise a constraint error
-
- if T'Machine_Overflows then
-raise Constraint_Error with "Pred of largest negative number";
-
- --  Otherwise generate a negative infinity
-
- else
-return X / (X - X);
- end if;
+ raise Constraint_Error with "Pred of largest negative number";
 
   --  For infinities, return unchanged
 
@@ -671,15 +662,10 @@ package body System.Fat_Gen is
 
  --  If not generating infinities, we raise a constraint error
 
- if T'Machine_Overflows then
-raise Constraint_Error with "Succ of largest negative number";
+ raise Constraint_Error with "Succ of largest positive number";
 
  --  Otherwise generate a positive infinity
 
- else
-return X / (X - X);
- end if;
-
   --  For infinities, return unchanged
 
   elsif X < T'First or else X > T'Last then

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/float_attributes_overflows.adb
@@ -0,0 +1,35 @@
+--  { dg-do run }
+
+procedure Float_Attributes_Overflows is
+
+   generic
+  type Float_Type is digits <>;
+   procedure Test_Float_Type;
+
+   procedure Test_Float_Type is
+   Biggest_Positive_float : Float_Type := Float_Type'Last;
+   Biggest_Negative_Float : Float_Type := Float_Type'First;
+   Float_Var : Float_Type;
+
+begin
+   begin
+ Float_Var := Float_Type'succ (Biggest_Positive_Float);
+ raise Program_Error;
+   exception
+  when Constraint_Error => null;
+   end;
+
+   begin
+ Float_Var := Float_Type'pred (Biggest_Negative_Float);
+ raise Program_Error;
+   exception
+  when Constraint_Error => null;
+   end;
+   end Test_Float_Type;
+
+   procedure Test_Float is new Test_Float_Type (Float);
+   procedure Test_Long_Float is new Test_Float_Type (Long_Float);
+begin
+   Test_Float;
+   Test_Long_Float;
+end Float_Attributes_Overflows;



[Ada] Tighten crtbegin files for VxWorks

2018-05-29 Thread Pierre-Marie de Rodat
Enforce a more explicit distinction of crtbegin objects holding
either functions with ctor/dtor attributes or _ctors/_dtors arrays,
or none of the two (no array, no attributes). Then allow/enforce
different linking strategies for VxWorks 7.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Olivier Hainque  

gcc/ada/

* vx_crtbegin.inc: Use a consistent naming convention for the
registration/deregistration functions across RTP or kernel.  Remove the
ctor/dtor attribute setting based on RTP/kernel, expect the optional
attribute extension to be provided by includers instead.
* vx_crtbegin.c: Mere inclusion of vx_crtbegin.inc with empty attribute
extension for the registration/deregistration functions.
* vx_crtbegin_attr.c: New file. Include vx_crtbegin.inc with explicit
constructor/destructor attribute extensions.
* vx_crtbegin_array.c: New file. Include vx_crtbegin.inc with empty
attribute extensions and declare _ctors/_dtors arrays.
* vx_crtbegin_auto.c: Remove.
* libgnat/system-vxworks7-aarch64-rtp-smp.ads: Use
vxworks7-gnat-crtbe-link.spec.
* libgnat/system-vxworks7-aarch64.ads: Likewise.
* libgnat/system-vxworks7-e500-rtp-smp.ads: Likewise.
* libgnat/system-vxworks7-ppc-rtp-smp.ads: Likewise.
* libgnat/system-vxworks7-ppc64-rtp-smp.ads: Likewise.
* libgnat/system-vxworks7-x86-kernel.ads: Likewise.
* libgnat/system-vxworks7-x86-rtp-smp.ads: Likewise.
* libgnat/system-vxworks7-x86_64-kernel.ads: Likewise.
* libgnat/system-vxworks7-x86_64-rtp-smp.ads: Likewise.--- gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
+++ gcc/ada/libgnat/system-vxworks7-aarch64-rtp-smp.ads
@@ -120,7 +120,7 @@ package System is
 
 private
 
-   pragma Linker_Options ("--specs=vxworks-gnat-crtbe-link.spec");
+   pragma Linker_Options ("--specs=vxworks7-gnat-crtbe-link.spec");
--  Pull in crtbegin/crtend objects and register exceptions for ZCX.
--  This is commented out by our Makefile for SJLJ runtimes.
 

--- gcc/ada/libgnat/system-vxworks7-aarch64.ads
+++ gcc/ada/libgnat/system-vxworks7-aarch64.ads
@@ -120,7 +120,7 @@ package System is
 
 private
 
-   pragma Linker_Options ("--specs=vxworks-gnat-crtbe-link.spec");
+   pragma Linker_Options ("--specs=vxworks7-gnat-crtbe-link.spec");
--  Pull in crtbegin/crtend objects and register exceptions for ZCX.
--  This is commented out by our Makefile for SJLJ runtimes.
 

--- gcc/ada/libgnat/system-vxworks7-e500-rtp-smp.ads
+++ gcc/ada/libgnat/system-vxworks7-e500-rtp-smp.ads
@@ -120,7 +120,7 @@ package System is
 
 private
 
-   pragma Linker_Options ("--specs=vxworks-gnat-crtbe-link.spec");
+   pragma Linker_Options ("--specs=vxworks7-gnat-crtbe-link.spec");
--  Pull in crtbegin/crtend objects and register exceptions for ZCX.
--  This is commented out by our Makefile for SJLJ runtimes.
 

--- gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
+++ gcc/ada/libgnat/system-vxworks7-ppc-rtp-smp.ads
@@ -120,7 +120,7 @@ package System is
 
 private
 
-   pragma Linker_Options ("--specs=vxworks-gnat-crtbe-link.spec");
+   pragma Linker_Options ("--specs=vxworks7-gnat-crtbe-link.spec");
--  Pull in crtbegin/crtend objects and register exceptions for ZCX.
--  This is commented out by our Makefile for SJLJ runtimes.
 

--- gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
+++ gcc/ada/libgnat/system-vxworks7-ppc64-rtp-smp.ads
@@ -120,7 +120,7 @@ package System is
 
 private
 
-   pragma Linker_Options ("--specs=vxworks-gnat-crtbe-link.spec");
+   pragma Linker_Options ("--specs=vxworks7-gnat-crtbe-link.spec");
--  Pull in crtbegin/crtend objects and register exceptions for ZCX.
--  This is commented out by our Makefile for SJLJ runtimes.
 

--- gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
+++ gcc/ada/libgnat/system-vxworks7-x86-kernel.ads
@@ -118,7 +118,7 @@ package System is
 
 private
 
-   pragma Linker_Options ("--specs=vxworks-gnat-crtbe-link.spec");
+   pragma Linker_Options ("--specs=vxworks7-gnat-crtbe-link.spec");
--  Pull in crtbegin/crtend objects and register exceptions for ZCX.
--  This is commented out by our Makefile for SJLJ runtimes.
 

--- gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
+++ gcc/ada/libgnat/system-vxworks7-x86-rtp-smp.ads
@@ -118,7 +118,7 @@ package System is
 
 private
 
-   pragma Linker_Options ("--specs=vxworks-gnat-crtbe-link.spec");
+   pragma Linker_Options ("--specs=vxworks7-gnat-crtbe-link.spec");
--  Pull in crtbegin/crtend objects and register exceptions for ZCX.
--  This is commented out by our Makefile for SJLJ runtimes.
 

--- gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
+++ gcc/ada/libgnat/system-vxworks7-x86_64-kernel.ads
@@ -118,7 +118,7 @@ package System is
 
 private
 
-   pragma Linker_Options ("--specs=vxworks-gnat-crtbe-link.spec");
+   pragma Linker_Options ("--specs=vxworks7-gnat-crtbe-link.spec");
 

[Ada] Plug small hole in -gnatR output

2018-05-29 Thread Pierre-Marie de Rodat
The -gnatR switch outputs representation information for locally-defined
types but it was skipping those defined in blocks without label, unlike
those defined in named blocks.  This change plugs this small hole.

The following procedure:

procedure P is
begin
  declare
type R is record
  I : Integer;
end record;
  begin
null;
  end;
end;

must now generate the following output with -gnatR:

Representation information for unit P (body)


for B_1.R'Size use 32;
for B_1.R'Alignment use 4;
for B_1.R use record
   I at 0 range  0 .. 31;
end record;

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Eric Botcazou  

gcc/ada/

* repinfo.adb (List_Entities): Also recurse into blocks without label.--- gcc/ada/repinfo.adb
+++ gcc/ada/repinfo.adb
@@ -408,7 +408,12 @@ package body Repinfo is
 --  info for the full view). If debug flag A is set, then all
 --  entities are listed
 
-if (Comes_From_Source (E)
+if ((Comes_From_Source (E)
+   or else (Ekind (E) = E_Block
+  and then
+Nkind (Parent (E)) = N_Implicit_Label_Declaration
+  and then
+Comes_From_Source (Label_Construct (Parent (E)
   and then not Is_Incomplete_Or_Private_Type (E)
   and then not (Ekind (E) = E_Constant
   and then Present (Full_View (E



[Ada] Add system-vxworks7 variants of system.ads files for Vx7

2018-05-29 Thread Pierre-Marie de Rodat
Based on the Vx6 versions, using a different link spec to accomodate VxWorks 7
specificities, in particular the ability in some configurations to rely on
.ctor sections to trigger constructors in kernel modules.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Olivier Hainque  

gcc/ada/

* libgnat/system-vxworks7-ppc-rtp.ads: New file.
* libgnat/system-vxworks7-ppc-kernel.ads: New file.
* libgnat/system-vxworks7-e500-rtp.ads: New file.
* libgnat/system-vxworks7-e500-kernel.ads: New file.
* libgnat/system-vxworks7-x86-rtp.ads: New file.
* libgnat/system-vxworks-ppc64-kernel.ads: Rename as ...
* libgnat/system-vxworks7-ppc64-kernel.ads: and adjust name of
gnat-crtbe link spec to use the vx7 variant.--- gcc/ada/libgnat/system-vxworks-ppc64-kernel.ads
deleted file mode 100644
+++ /dev/null
@@ -1,168 +0,0 @@
---
---  --
---GNAT RUN-TIME COMPONENTS  --
---  --
---   S Y S T E M--
---  --
--- S p e c  --
---   (VxWorks 7.x PPC64 Kernel) --
---  --
---  Copyright (C) 1992-2018, Free Software Foundation, Inc. --
---  --
--- This specification is derived from the Ada Reference Manual for use with --
--- GNAT. The copyright notice above, and the license provisions that follow --
--- apply solely to the  contents of the part following the private keyword. --
---  --
--- GNAT is free software;  you can  redistribute it  and/or modify it under --
--- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 3,  or (at your option) any later ver- --
--- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE. --
---  --
--- As a special exception 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--
--- .  --
---  --
--- GNAT was originally developed  by the GNAT team at  New York University. --
--- Extensive contributions were provided by Ada Core Technologies Inc.  --
---  --
---
-
---  This is the VxWorks 7.x version of this package for PPC64 Kernel
-
-package System is
-   pragma Pure;
-   --  Note that we take advantage of the implementation permission to make
-   --  this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-   --  2005, this is Pure in any case (AI-362).
-
-   pragma No_Elaboration_Code_All;
-   --  Allow the use of that restriction in units that WITH this unit
-
-   type Name is (SYSTEM_NAME_GNAT);
-   System_Name : constant Name := SYSTEM_NAME_GNAT;
-
-   --  System-Dependent Named Numbers
-
-   Min_Int   : constant := Long_Long_Integer'First;
-   Max_Int   : constant := Long_Long_Integer'Last;
-
-   Max_Binary_Modulus: constant := 2 ** Long_Long_Integer'Size;
-   Max_Nonbinary_Modulus : constant := 2 ** Integer'Size - 1;
-
-   Max_Base_Digits   : constant := Long_Long_Float'Digits;
-   Max_Digits: constant := Long_Long_Float'Digits;
-
-   Max_Mantissa  : constant := 63;
-   Fine_Delta: constant := 2.0 ** (-Max_Mantissa);
-
-   Tick  : constant := 1.0 / 60.0;
-
-   --  Storage-related Declarations
-
-   type Address is private;
-   pragma Preelaborable_Initialization (Address);
-   Null_Address : constant Address;
-
-   Storage_Unit : constant := 

[Ada] Implement machine parsable format for -gnatR output

2018-05-29 Thread Pierre-Marie de Rodat
This adds a new variant to the -gnatR switch, namely -gnatRj, which causes
the compiler to output representation information to a file in the JSON
data interchange format.  It can be combined with -gnatR0/1/2/3/m (but is
incompatible with -gnaRe and -gnatRs).

The information output in this mode is a superset of that output in the
traditional -gnatR mode, but is otherwise equivalent for the common part.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Eric Botcazou  

gcc/ada/

* doc/gnat_ugn/building_executable_programs_with_gnat.rst (Alphabetical
List of All Switches): Document -gnatRj.
(Debugging Control): Likewise.
* gnat_ugn.texi: Regenerate.
* opt.ads (List_Representation_Info_To_JSON): New boolean variable.
* osint-c.adb (Create_Repinfo_File): Use the .json instead of .rep
extension if List_Representation_Info_To_JSON is true.
* repinfo.ads: Document the JSON output format.
* repinfo.adb (List_Location): New procedure.
(List_Array_Info): Add support for JSON output.
(List_Entities): Likewise.
(Unop): Likewise.
(Binop): Likewise.
(Print_Expr): Likewise.
(List_Linker_Section): Likewise.
(List_Mechanisms): Likewise.
(List_Name): Likewise.
(List_Object_Info): Likewise.
(List_Record_Info): Likewise.
(List_Component_Layout): Likewise.  Add Indent parameter.
(List_Structural_Record_Layout): New procedure.
(List_Attr): Add support for JSON output.
(List_Type_Info): Likewise.
(Write_Unknown_Val): Likewise.
* switch-c.adb (Scan_Front_End_Switches) : Deal with 'j'.
* usage.adb (Usage): List -gnatRj.--- gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -2024,7 +2024,7 @@ Alphabetical List of All Switches
 
 .. index:: -gnatR  (gcc)
 
-:switch:`-gnatR[0/1/2/3][e][m][s]`
+:switch:`-gnatR[0|1|2|3][e][j][m][s]`
   Output representation information for declared types, objects and
   subprograms. Note that this switch is not allowed if a previous
   :switch:`-gnatD` switch has been given, since these two switches
@@ -5786,7 +5786,7 @@ Debugging Control
 
 .. index:: -gnatR  (gcc)
 
-:switch:`-gnatR[0|1|2|3][e][m][s]`
+:switch:`-gnatR[0|1|2|3][e][j][m][s]`
   This switch controls output from the compiler of a listing showing
   representation information for declared types, objects and subprograms.
   For :switch:`-gnatR0`, no information is output (equivalent to omitting
@@ -5817,6 +5817,13 @@ Debugging Control
   the output is to a file with the name :file:`file.rep` where file is
   the name of the corresponding source file.
 
+  If the switch is followed by a ``j`` (e.g., :switch:`-gnatR3j`), then
+  the output is to a file with the name :file:`file.json` where file is
+  the name of the corresponding source file, and it uses the JSON data
+  interchange format specified by the ECMA-404 standard. The semantic
+  description of this JSON output is available in the specification of
+  the Repinfo unit present in the compiler sources.
+
   Note that it is possible for record components to have zero size. In
   this case, the component clause uses an obvious extension of permitted
   Ada syntax, for example ``at 0 range 0 .. -1``.

--- gcc/ada/gnat_ugn.texi
+++ gcc/ada/gnat_ugn.texi
@@ -9898,7 +9898,7 @@ Treat pragma Restrictions as Restriction_Warnings.
 
 @table @asis
 
-@item @code{-gnatR[0/1/2/3][e][m][s]}
+@item @code{-gnatR[0|1|2|3][e][j][m][s]}
 
 Output representation information for declared types, objects and
 subprograms. Note that this switch is not allowed if a previous
@@ -15013,7 +15013,7 @@ restriction warnings rather than restrictions.
 
 @table @asis
 
-@item @code{-gnatR[0|1|2|3][e][m][s]}
+@item @code{-gnatR[0|1|2|3][e][j][m][s]}
 
 This switch controls output from the compiler of a listing showing
 representation information for declared types, objects and subprograms.
@@ -15045,6 +15045,13 @@ If the switch is followed by an @code{s} (e.g., @code{-gnatR3s}), then
 the output is to a file with the name @code{file.rep} where file is
 the name of the corresponding source file.
 
+If the switch is followed by a @code{j} (e.g., @code{-gnatR3j}), then
+the output is to a file with the name @code{file.json} where file is
+the name of the corresponding source file, and it uses the JSON data
+interchange format specified by the ECMA-404 standard. The semantic
+description of this JSON output is available in the specification of
+the Repinfo unit present in the compiler sources.
+
 Note that it is possible for record components to have zero size. In
 this case, the component clause uses an obvious extension of permitted
 Ada syntax, for example @code{at 0 range 0 .. -1}.

--- gcc/ada/opt.ads
+++ gcc/ada/opt.ads
@@ -1003,6 +1003,12 @@ package Opt is
--  of stdout. For example, if file x.adb is 

[Ada] Fix constraint error in Normalize_Pathname

2018-05-29 Thread Pierre-Marie de Rodat
Fix Normalize_Pathname to avoid a constraint error.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Pascal Obry  

gcc/ada/

* libgnat/s-os_lib.adb (Normalize_Pathname): Fix handling of ".." in
the root directory.

gcc/testsuite/

* gnat.dg/normalize_pathname.adb: New testcase.--- gcc/ada/libgnat/s-os_lib.adb
+++ gcc/ada/libgnat/s-os_lib.adb
@@ -2389,12 +2389,18 @@ package body System.OS_Lib is
  elsif Finish = Start + 1
and then Path_Buffer (Start .. Finish) = ".."
  then
-Start := Last;
-loop
-   Start := Start - 1;
-   exit when Start = 1
- or else Path_Buffer (Start) = Directory_Separator;
-end loop;
+if Last > 1 then
+   Start := Last - 1;
+
+   while Start > 1
+ and then Path_Buffer (Start) /= Directory_Separator
+   loop
+  Start := Start - 1;
+   end loop;
+
+else
+   Start := Last;
+end if;
 
 if Start = 1 then
if Finish = End_Path then

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/normalize_pathname.adb
@@ -0,0 +1,10 @@
+--  { dg-do run }
+
+with GNAT.OS_Lib;
+
+procedure Normalize_Pathname is
+   S : constant String := GNAT.OS_Lib.Normalize_Pathname
+ ("/../tmp", Directory => "", Resolve_Links => True);
+begin
+   null;
+end Normalize_Pathname;



[Ada] Enhance output of discriminants with -gnatR in JSON mode

2018-05-29 Thread Pierre-Marie de Rodat
This arranges for the Discriminant_Number of discriminants to be output
by -gnatR in JSON mode.  This number is referenced in symbolic expressions
present for offsets and sizes, so its definition is also required for the
sake of completeness.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Eric Botcazou  

gcc/ada/

* repinfo.ads (JSON format): Document new pair for components.
* repinfo.adb (Derived_Discriminant): New function.
(List_Structural_Record_Layout): Add Outer_Ent parameter and pass it
in recursive calls. If the record type is the parent of an extension,
find and list the derived discriminant from the extension, if any.
(List_Component_Layout): List the Discriminant_Number in JSON mode.
(List_Record_Info): Adjust call to List_Structural_Record_Layout.--- gcc/ada/repinfo.adb
+++ gcc/ada/repinfo.adb
@@ -207,8 +207,8 @@ package body Repinfo is
 
function Back_End_Layout return Boolean is
begin
-  --  We have back end layout if the back end has made any entries in the
-  --  table of GCC expressions, otherwise we have front end layout.
+  --  We have back-end layout if the back end has made any entries in the
+  --  table of GCC expressions, otherwise we have front-end layout.
 
   return Rep_Table.Last > 0;
end Back_End_Layout;
@@ -1069,9 +1069,10 @@ package body Repinfo is
   --  Internal recursive procedure to display the layout
 
   procedure List_Structural_Record_Layout
-(Ent : Entity_Id;
- Variant : Node_Id := Empty;
- Indent  : Natural := 0);
+(Ent   : Entity_Id;
+ Outer_Ent : Entity_Id;
+ Variant   : Node_Id := Empty;
+ Indent: Natural := 0);
   --  Internal recursive procedure to display the structural layout
 
   Max_Name_Length : Natural := 0;
@@ -1205,6 +1206,12 @@ package body Repinfo is
 Write_Str (Prefix);
 Write_Str (Name_Buffer (1 .. Name_Len));
 Write_Line (""",");
+if Ekind (Ent) = E_Discriminant then
+   Spaces (Indent);
+   Write_Str ("  ""discriminant"": ");
+   UI_Write (Discriminant_Number (Ent));
+   Write_Line (",");
+end if;
 Spaces (Indent);
 Write_Str ("  ""Position"": ");
  else
@@ -1304,8 +1311,8 @@ package body Repinfo is
  else
 Write_Val (Esiz, Paren => not List_Representation_Info_To_JSON);
 
---  If in front end layout mode, then dynamic size is stored
---  in storage units, so renormalize for output
+--  If in front-end layout mode, then dynamic size is stored
+--  in storage units, so renormalize for output.
 
 if not Back_End_Layout then
Write_Str (" * ");
@@ -1416,15 +1423,67 @@ package body Repinfo is
   ---
 
   procedure List_Structural_Record_Layout
-(Ent : Entity_Id;
- Variant : Node_Id := Empty;
- Indent  : Natural := 0)
+(Ent   : Entity_Id;
+ Outer_Ent : Entity_Id;
+ Variant   : Node_Id := Empty;
+ Indent: Natural := 0)
   is
+
+ function Derived_Discriminant (Disc : Entity_Id) return Entity_Id;
+ --  This function assumes that Outer_Ent is an extension of Ent.
+ --  Disc is a discriminant of Ent that does not itself constrain a
+ --  discriminant of the parent type of Ent. Return the discriminant
+ --  of Outer_Ent that ultimately constrains Disc, if any.
+
+ 
+ --  Derived_Discriminant  --
+ 
+
+ function Derived_Discriminant (Disc : Entity_Id) return Entity_Id is
+Corr_Disc, Derived_Disc : Entity_Id;
+
+ begin
+Derived_Disc := First_Stored_Discriminant (Outer_Ent);
+
+--  Loop over the discriminants of the extension
+
+while Present (Derived_Disc) loop
+
+   --  Check if this discriminant constrains another discriminant.
+   --  If so, find the ultimately constrained discriminant and
+   --  compare with the original components in the base type.
+
+   if Present (Corresponding_Discriminant (Derived_Disc)) then
+  Corr_Disc := Corresponding_Discriminant (Derived_Disc);
+
+  while Present (Corresponding_Discriminant (Corr_Disc)) loop
+ Corr_Disc := Corresponding_Discriminant (Corr_Disc);
+  end loop;
+
+  if Original_Record_Component (Corr_Disc)
+ = Original_Record_Component (Disc)
+  then
+ return Derived_Disc;
+  end if;
+   end if;
+
+   Next_Stored_Discriminant (Derived_Disc);
+

[Ada] Adjustment of behavior of new -gnatRj switch

2018-05-29 Thread Pierre-Marie de Rodat
This decouples -gnatRj from the destination, either standard output or file,
so that it only toggles the format of the representation information.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Eric Botcazou  

gcc/ada/

* doc/gnat_ugn/building_executable_programs_with_gnat.rst (Debugging
Control): Adjust description of -gnatRj.
* gnat_ugn.texi: Regenerate.
* opt.ads (List_Representation_Info_To_JSON): Likewise.
* repinfo.adb (List_Rep_Info): Do not automatically create a file
if List_Representation_Info_To_JSON is true.
* switch-c.adb (Scan_Front_End_Switches) : Remove incompatibility
check between -gnatRj and -gnatRs.
* usage.adb (Usage): Adjust description of -gnatRj.--- gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -5813,16 +5813,16 @@ Debugging Control
   subprogram conventions and parameter passing mechanisms for all the
   subprograms are included.
 
+  If the switch is followed by a ``j`` (e.g., :switch:`-gnatRj`), then
+  the output is in the JSON data interchange format specified by the
+  ECMA-404 standard. The semantic description of this JSON output is
+  available in the specification of the Repinfo unit present in the
+  compiler sources.
+
   If the switch is followed by an ``s`` (e.g., :switch:`-gnatR3s`), then
   the output is to a file with the name :file:`file.rep` where file is
-  the name of the corresponding source file.
-
-  If the switch is followed by a ``j`` (e.g., :switch:`-gnatR3j`), then
-  the output is to a file with the name :file:`file.json` where file is
-  the name of the corresponding source file, and it uses the JSON data
-  interchange format specified by the ECMA-404 standard. The semantic
-  description of this JSON output is available in the specification of
-  the Repinfo unit present in the compiler sources.
+  the name of the corresponding source file, except if `j`` is also
+  specified, in which case the file name is :file:`file.json`.
 
   Note that it is possible for record components to have zero size. In
   this case, the component clause uses an obvious extension of permitted

--- gcc/ada/gnat_ugn.texi
+++ gcc/ada/gnat_ugn.texi
@@ -15041,16 +15041,16 @@ If the switch is followed by an @code{m} (e.g. @code{-gnatRm}), then
 subprogram conventions and parameter passing mechanisms for all the
 subprograms are included.
 
+If the switch is followed by a @code{j} (e.g., @code{-gnatRj}), then
+the output is in the JSON data interchange format specified by the
+ECMA-404 standard. The semantic description of this JSON output is
+available in the specification of the Repinfo unit present in the
+compiler sources.
+
 If the switch is followed by an @code{s} (e.g., @code{-gnatR3s}), then
 the output is to a file with the name @code{file.rep} where file is
-the name of the corresponding source file.
-
-If the switch is followed by a @code{j} (e.g., @code{-gnatR3j}), then
-the output is to a file with the name @code{file.json} where file is
-the name of the corresponding source file, and it uses the JSON data
-interchange format specified by the ECMA-404 standard. The semantic
-description of this JSON output is available in the specification of
-the Repinfo unit present in the compiler sources.
+the name of the corresponding source file, except if @cite{j`} is also
+specified, in which case the file name is @code{file.json}.
 
 Note that it is possible for record components to have zero size. In
 this case, the component clause uses an obvious extension of permitted

--- gcc/ada/opt.ads
+++ gcc/ada/opt.ads
@@ -1006,8 +1006,7 @@ package Opt is
List_Representation_Info_To_JSON : Boolean := False;
--  GNAT
--  Set true by -gnatRj switch. Causes information from -gnatR/1/2/3/m to be
-   --  written to file.json (where file is the name of the source file) in the
-   --  JSON data interchange format.
+   --  output in the JSON data interchange format.
 
List_Representation_Info_Mechanisms : Boolean := False;
--  GNAT

--- gcc/ada/repinfo.adb
+++ gcc/ada/repinfo.adb
@@ -1711,20 +1711,21 @@ package body Repinfo is
 
--  Normal case, list to standard output
 
-   if not List_Representation_Info_To_File
- and then not List_Representation_Info_To_JSON
-   then
-  Write_Eol;
-  Write_Str ("Representation information for unit ");
-  Write_Unit_Name (Unit_Name (U));
-  Col := Column;
-  Write_Eol;
-
-  for J in 1 .. Col - 1 loop
- Write_Char ('-');
-  end loop;
+   if not List_Representation_Info_To_File then
+  if not List_Representation_Info_To_JSON then
+ Write_Eol;
+ Write_Str ("Representation information for unit ");
+ 

[Ada] Factor out worker procedure for -gnatR

2018-05-29 Thread Pierre-Marie de Rodat
This extracts a worker procedure for printing the layout of a single component
from List_Record_Layout so as to make the next change more readable.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Eric Botcazou  

gcc/ada/

* repinfo.adb (List_Component_Layout): New procedure extracted from...
(List_Record_Layout): ...here.  Invoke it.--- gcc/ada/repinfo.adb
+++ gcc/ada/repinfo.adb
@@ -891,6 +891,13 @@ package body Repinfo is
  Prefix_Length  : Natural := 0);
   --  Internal recursive procedure to compute the max length
 
+  procedure List_Component_Layout
+(Ent: Entity_Id;
+ Starting_Position  : Uint := Uint_0;
+ Starting_First_Bit : Uint := Uint_0;
+ Prefix : String := "");
+  --  Procedure to display the layout of a single component
+
   procedure List_Record_Layout
 (Ent: Entity_Id;
  Starting_Position  : Uint := Uint_0;
@@ -1002,6 +1009,126 @@ package body Repinfo is
  end loop;
   end Compute_Max_Length;
 
+  ---
+  -- List_Component_Layout --
+  ---
+
+  procedure List_Component_Layout
+(Ent: Entity_Id;
+ Starting_Position  : Uint := Uint_0;
+ Starting_First_Bit : Uint := Uint_0;
+ Prefix : String := "")
+  is
+ Esiz  : constant Uint := Esize (Ent);
+ Npos  : constant Uint := Normalized_Position (Ent);
+ Fbit  : constant Uint := Normalized_First_Bit (Ent);
+ Spos  : Uint;
+ Sbit  : Uint;
+ Lbit  : Uint;
+
+  begin
+ Write_Str ("   ");
+ Write_Str (Prefix);
+ Write_Str (Name_Buffer (1 .. Name_Len));
+ Spaces (Max_Name_Length - Prefix'Length - Name_Len);
+ Write_Str (" at ");
+
+ if Known_Static_Normalized_Position (Ent) then
+Spos := Starting_Position  + Npos;
+Sbit := Starting_First_Bit + Fbit;
+
+if Sbit >= SSU then
+   Spos := Spos + 1;
+end if;
+
+UI_Image (Spos);
+Spaces (Max_Spos_Length - UI_Image_Length);
+Write_Str (UI_Image_Buffer (1 .. UI_Image_Length));
+
+ elsif Known_Normalized_Position (Ent)
+   and then List_Representation_Info = 3
+ then
+Spaces (Max_Spos_Length - 2);
+
+if Starting_Position /= Uint_0 then
+   UI_Write (Starting_Position);
+   Write_Str (" + ");
+end if;
+
+Write_Val (Npos);
+
+ else
+Write_Unknown_Val;
+ end if;
+
+ Write_Str (" range  ");
+ Sbit := Starting_First_Bit + Fbit;
+
+ if Sbit >= SSU then
+Sbit := Sbit - SSU;
+ end if;
+
+ UI_Write (Sbit);
+ Write_Str (" .. ");
+
+ --  Allowing Uint_0 here is an annoying special case. Really
+ --  this should be a fine Esize value but currently it means
+ --  unknown, except that we know after gigi has back annotated
+ --  that a size of zero is real, since otherwise gigi back
+ --  annotates using No_Uint as the value to indicate unknown.
+
+ if (Esize (Ent) = Uint_0 or else Known_Static_Esize (Ent))
+   and then Known_Static_Normalized_First_Bit (Ent)
+ then
+Lbit := Sbit + Esiz - 1;
+
+if Lbit < 10 then
+   Write_Char (' ');
+end if;
+
+UI_Write (Lbit);
+
+ --  The test for Esize (Ent) not Uint_0 here is an annoying
+ --  special case. Officially a value of zero for Esize means
+ --  unknown, but here we use the fact that we know that gigi
+ --  annotates Esize with No_Uint, not Uint_0. Really everyone
+ --  should use No_Uint???
+
+ elsif List_Representation_Info < 3
+   or else (Esize (Ent) /= Uint_0 and then Unknown_Esize (Ent))
+ then
+Write_Unknown_Val;
+
+ --  List_Representation >= 3 and Known_Esize (Ent)
+
+ else
+Write_Val (Esiz, Paren => True);
+
+--  If in front end layout mode, then dynamic size is stored
+--  in storage units, so renormalize for output
+
+if not Back_End_Layout then
+   Write_Str (" * ");
+   Write_Int (SSU);
+end if;
+
+--  Add appropriate first bit offset
+
+if Sbit = 0 then
+   Write_Str (" - 1");
+
+elsif Sbit = 1 then
+   null;
+
+else
+   Write_Str (" + ");
+   Write_Int (UI_To_Int (Sbit) - 1);
+end if;
+ end if;
+
+ Write_Line (";");
+  end List_Component_Layout;
+
   
   -- List_Record_Layout --
   
@@ -1036,12 +1163,10 @@ package body Repinfo 

[Ada] Minor cleanup in repinfo unit

2018-05-29 Thread Pierre-Marie de Rodat
This factors out the various cases where a marker for an unknown value is
output by the -gnatR switches.  No functional changes.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Eric Botcazou  

gcc/ada/

* repinfo.adb (Write_Unknown_Val): New procedure.
(List_GCC_Expression): Call it.
(List_Record_Layout): Likewise.
(Write_Val): Likewise.--- gcc/ada/repinfo.adb
+++ gcc/ada/repinfo.adb
@@ -189,6 +189,9 @@ package body Repinfo is
procedure Write_Mechanism (M : Mechanism_Type);
--  Writes symbolic string for mechanism represented by M
 
+   procedure Write_Unknown_Val;
+   --  Writes symbolic string for an unknown or non-representable value
+
procedure Write_Val (Val : Node_Ref_Or_Val; Paren : Boolean := False);
--  Given a representation value, write it out. No_Uint values or values
--  dependent on discriminants are written as two question marks. If the
@@ -653,7 +656,7 @@ package body Repinfo is
 
begin
   if U = No_Uint then
- Write_Str ("??");
+ Write_Unknown_Val;
   else
  Print_Expr (U);
   end if;
@@ -,7 +1114,7 @@ package body Repinfo is
   --  Otherwise we can continue
 
   else
- Write_Str ("??");
+ Write_Unknown_Val;
   end if;
end if;
 
@@ -1128,8 +1131,8 @@ package body Repinfo is
--  Allowing Uint_0 here is an annoying special case. Really
--  this should be a fine Esize value but currently it means
--  unknown, except that we know after gigi has back annotated
-   --  that a size  of zero is real, since otherwise gigi back
-   --  annotates using No_Uint as the value to indicate unknown).
+   --  that a size of zero is real, since otherwise gigi back
+   --  annotates using No_Uint as the value to indicate unknown.
 
if (Esize (Comp) = Uint_0 or else Known_Static_Esize (Comp))
  and then Known_Static_Normalized_First_Bit (Comp)
@@ -1151,7 +1154,7 @@ package body Repinfo is
elsif List_Representation_Info < 3
  or else (Esize (Comp) /= Uint_0 and then Unknown_Esize (Comp))
then
-  Write_Str ("??");
+  Write_Unknown_Val;
 
--  List_Representation >= 3 and Known_Esize (Comp)
 
@@ -1674,6 +1677,15 @@ package body Repinfo is
   end case;
end Write_Mechanism;
 
+   ---
+   -- Write_Unknown_Val --
+   ---
+
+   procedure Write_Unknown_Val is
+   begin
+  Write_Str ("??");
+   end Write_Unknown_Val;
+
---
-- Write_Val --
---
@@ -1682,7 +1694,7 @@ package body Repinfo is
begin
   if Rep_Not_Constant (Val) then
  if List_Representation_Info < 3 or else Val = No_Uint then
-Write_Str ("??");
+Write_Unknown_Val;
 
  else
 if Paren then



[Ada] Fix irregular output with -gnatRm

2018-05-29 Thread Pierre-Marie de Rodat
The information displayed by -gnatRm was using slightly different naming
and formatting conventions than the rest of the -gnatR information with
no justification, so this adjusts it for the sake of consistency.

For the following package:

package P is

  function F (I : Integer) return Integer;

  type Rec is limited record
I : Integer;
  end record;

  procedure P1 (R : Rec; I : out Integer);

  procedure P2 (R : Rec; I : out Integer);
  pragma Linker_Section (P2, ".my_section");

  package Inner is

procedure P3;

  end Inner;

end P;

package body P is

  function F (I : Integer) return Integer is
  begin
return I;
  end;

  procedure P1 (R : Rec; I : out Integer) is
  begin
I := R.I;
  end;

  procedure P2 (R : Rec; I : out Integer) is
  begin
I := R.I;
  end;

  package body Inner is

 procedure P3 is
 begin
   null;
 end;

  end Inner;

end P;

the output of -gnatRm must be:

Representation information for unit P (body)


Representation information for unit P (spec)


function F declared at p7.ads:3:12
convention : Ada
   I : passed by copy
returns by copy

for Rec'Size use 32;
for Rec'Alignment use 4;
for Rec use record
   I at 0 range  0 .. 31;
end record;

procedure P1 declared at p7.ads:9:13
convention : Ada
   R : passed by reference
   I : passed by copy

procedure P2 declared at p7.ads:11:13
convention : Ada
   R : passed by reference
   I : passed by copy
pragma Linker_Section (P2, ".my_section");

procedure Inner.P3 declared at p7.ads:16:15
convention : Ada

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Eric Botcazou  

gcc/ada/

* repinfo.adb (List_Entities): Do not list the Linker_Section for
subprograms here...
(List_Mechanisms): ...but here instead.  Use consistent name output
and formatting conventions.--- gcc/ada/repinfo.adb
+++ gcc/ada/repinfo.adb
@@ -393,8 +393,6 @@ package body Repinfo is
   or else Debug_Flag_AA
 then
if Is_Subprogram (E) then
-  List_Linker_Section (E);
-
   if List_Representation_Info_Mechanisms then
  List_Mechanisms (E);
   end if;
@@ -746,13 +744,12 @@ package body Repinfo is
 raise Program_Error;
   end case;
 
-  Get_Unqualified_Decoded_Name_String (Chars (Ent));
-  Write_Str (Name_Buffer (1 .. Name_Len));
+  List_Name (Ent);
   Write_Str (" declared at ");
   Write_Location (Sloc (Ent));
   Write_Eol;
 
-  Write_Str ("  convention : ");
+  Write_Str ("convention : ");
 
   case Convention (Ent) is
  when Convention_Ada =>
@@ -814,12 +811,13 @@ package body Repinfo is
   Form := First_Formal (Ent);
   while Present (Form) loop
  Get_Unqualified_Decoded_Name_String (Chars (Form));
+ Set_Casing (Unit_Casing);
  while Name_Len <= Plen loop
 Name_Len := Name_Len + 1;
 Name_Buffer (Name_Len) := ' ';
  end loop;
 
- Write_Str ("  ");
+ Write_Str ("   ");
  Write_Str (Name_Buffer (1 .. Plen + 1));
  Write_Str (": passed by ");
 
@@ -829,10 +827,14 @@ package body Repinfo is
   end loop;
 
   if Etype (Ent) /= Standard_Void_Type then
- Write_Str ("  returns by ");
+ Write_Str ("returns by ");
  Write_Mechanism (Mechanism (Ent));
  Write_Eol;
   end if;
+
+  if not Is_Entry (Ent) then
+ List_Linker_Section (Ent);
+  end if;
end List_Mechanisms;
 
---



[Ada] Preliminary work to avoid full pathnames in ALI files

2018-05-29 Thread Pierre-Marie de Rodat
Normally, ALI files refer to source files using simple names. This allows files
to be moved around without disturbing things (causing extra recompilations,
etc). However, for configuration files, the full pathname is stored. This patch
preparates the code base to store the simple name in this case.

Tested on x86_64-pc-linux-gnu, committed on trunk

2018-05-29  Bob Duff  

gcc/ada/

* lib-writ.adb (Write_ALI): Cleanup: avoid use of global var; call new
To_Lower function.
* libgnat/s-casuti.ads, libgnat/s-casuti.adb (To_Upper, To_Lower,
To_Mixed): New functions.
* osint.adb: Cleanup: use Is_Directory_Separator, which correctly
allows both '\' and '/' on Windows.--- gcc/ada/lib-writ.adb
+++ gcc/ada/lib-writ.adb
@@ -1539,15 +1539,21 @@ package body Lib.Writ is
 --  Normal case of a unit entry with a source index
 
 if Sind > No_Source_File then
-   Fname := File_Name (Sind);
+   --  We never want directory information in ALI files
+   --  ???But back out this change temporarily until
+   --  gprbuild is fixed.
 
-   --  Ensure that on platforms where the file names are not case
-   --  sensitive, the recorded file name is in lower case.
+   if False then
+  Fname := Strip_Directory (File_Name (Sind));
+   else
+  Fname := File_Name (Sind);
+   end if;
+
+   --  Ensure that on platforms where the file names are not
+   --  case sensitive, the recorded file name is in lower case.
 
if not File_Names_Case_Sensitive then
-  Get_Name_String (Fname);
-  To_Lower (Name_Buffer (1 .. Name_Len));
-  Fname := Name_Find;
+  Fname := Name_Find (To_Lower (Get_Name_String (Fname)));
end if;
 
Write_Info_Name_May_Be_Quoted (Fname);

--- gcc/ada/libgnat/s-casuti.adb
+++ gcc/ada/libgnat/s-casuti.adb
@@ -58,6 +58,13 @@ package body System.Case_Util is
   end loop;
end To_Lower;
 
+   function To_Lower (A : String) return String is
+  Result : String := A;
+   begin
+  To_Lower (Result);
+  return Result;
+   end To_Lower;
+
--
-- To_Mixed --
--
@@ -77,6 +84,13 @@ package body System.Case_Util is
   end loop;
end To_Mixed;
 
+   function To_Mixed (A : String) return String is
+  Result : String := A;
+   begin
+  To_Mixed (Result);
+  return Result;
+   end To_Mixed;
+
--
-- To_Upper --
--
@@ -102,4 +116,11 @@ package body System.Case_Util is
   end loop;
end To_Upper;
 
+   function To_Upper (A : String) return String is
+  Result : String := A;
+   begin
+  To_Upper (Result);
+  return Result;
+   end To_Upper;
+
 end System.Case_Util;

--- gcc/ada/libgnat/s-casuti.ads
+++ gcc/ada/libgnat/s-casuti.ads
@@ -49,6 +49,7 @@ package System.Case_Util is
--  returns the input argument unchanged.
 
procedure To_Upper (A : in out String);
+   function To_Upper (A : String) return String;
--  Folds all characters of string A to upper case
 
function To_Lower (A : Character) return Character;
@@ -56,9 +57,11 @@ package System.Case_Util is
--  returns the input argument unchanged.
 
procedure To_Lower (A : in out String);
+   function To_Lower (A : String) return String;
--  Folds all characters of string A to lower case
 
procedure To_Mixed (A : in out String);
+   function To_Mixed (A : String) return String;
--  Converts A to mixed case (i.e. lower case, except for initial
--  character and any character after an underscore, which are
--  converted to upper case.

--- gcc/ada/osint.adb
+++ gcc/ada/osint.adb
@@ -830,9 +830,7 @@ package body Osint is
   Add_Suffix := False;
   exit;
 
-   elsif Name_Buffer (J) = '/' or else
- Name_Buffer (J) = Directory_Separator
-   then
+   elsif Is_Directory_Separator (Name_Buffer (J)) then
   exit;
end if;
 end loop;
@@ -905,9 +903,7 @@ package body Osint is
  Add_Suffix := False;
  exit;
 
-  elsif Canonical_Name (J) = '/' or else
-Canonical_Name (J) = Directory_Separator
-  then
+  elsif Is_Directory_Separator (Canonical_Name (J)) then
  exit;
   end if;
end loop;
@@ -1501,7 +1497,7 @@ package body Osint is
   --  Add a directory separator at the end of the directory if necessary
   --  so that we can directly append a file to the directory
 
-  if Search_Dir (Search_Dir'Last) /= Directory_Separator then
+  if not Is_Directory_Separator (Search_Dir (Search_Dir'Last)) then
   

Re: [PATCH] Introduce VEC_UNPACK_FIX_TRUNC_{LO,HI}_EXPR and VEC_PACK_FLOAT_EXPR, use it in x86 vectorization (PR target/85918)

2018-05-29 Thread Jakub Jelinek
On Tue, May 29, 2018 at 11:15:51AM +0200, Richard Biener wrote:
> Looking at other examples the only thing we have is
> maybe_ne and friends on TYPE_VECTOR_SUBPARTS.  But I think the only
> thing missing is
> 
>  || (maybe_ne (TYPE_VECTOR_SUBPARTS (lhs_type),
>  2 * TYPE_VECTOR_SUBPARTS (rhs_type)))
> 
> that together with the mode size check should ensure same size
> vectors.

The other way around.  It would then be (and I've added similar tests for
VEC_PACK*):

2018-05-29  Jakub Jelinek  

* tree-cfg.c (verify_gimple_assign_unary): Add checking for
VEC_UNPACK_*_EXPR.
(verify_gimple_assign_binary): Check TYPE_VECTOR_SUBPARTS for
VEC_PACK_*_EXPR.

--- gcc/tree-cfg.c.jj   2018-05-28 19:47:55.180685259 +0200
+++ gcc/tree-cfg.c  2018-05-29 11:27:14.521339290 +0200
@@ -3678,7 +3678,37 @@ verify_gimple_assign_unary (gassign *stm
 case VEC_UNPACK_FLOAT_LO_EXPR:
 case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
 case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
-  /* FIXME.  */
+  if (TREE_CODE (rhs1_type) != VECTOR_TYPE
+  || TREE_CODE (lhs_type) != VECTOR_TYPE
+  || (!INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
+ && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type)))
+  || (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
+ && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type)))
+ || ((rhs_code == VEC_UNPACK_HI_EXPR
+  || rhs_code == VEC_UNPACK_LO_EXPR)
+ && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
+ != INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type
+ || ((rhs_code == VEC_UNPACK_FLOAT_HI_EXPR
+  || rhs_code == VEC_UNPACK_FLOAT_LO_EXPR)
+ && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
+ || SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type
+ || ((rhs_code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
+  || rhs_code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
+ && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
+ || SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type
+ || (maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
+   2 * GET_MODE_SIZE (element_mode (rhs1_type)))
+ && (!VECTOR_BOOLEAN_TYPE_P (lhs_type)
+ || !VECTOR_BOOLEAN_TYPE_P (rhs1_type)))
+ || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (lhs_type),
+  TYPE_VECTOR_SUBPARTS (rhs1_type)))
+   {
+ error ("type mismatch in vector unpack expression");
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ return true;
+}
+
   return false;
 
 case NEGATE_EXPR:
@@ -3993,7 +4023,9 @@ verify_gimple_assign_binary (gassign *st
 == INTEGRAL_TYPE_P (TREE_TYPE (lhs_type
|| !types_compatible_p (rhs1_type, rhs2_type)
|| maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
-2 * GET_MODE_SIZE (element_mode (lhs_type
+2 * GET_MODE_SIZE (element_mode (lhs_type)))
+   || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
+TYPE_VECTOR_SUBPARTS (lhs_type)))
   {
 error ("type mismatch in vector pack expression");
 debug_generic_expr (lhs_type);
@@ -4012,7 +4044,9 @@ verify_gimple_assign_binary (gassign *st
  || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))
  || !types_compatible_p (rhs1_type, rhs2_type)
  || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
-  2 * GET_MODE_SIZE (element_mode (lhs_type
+  2 * GET_MODE_SIZE (element_mode (lhs_type)))
+ || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
+  TYPE_VECTOR_SUBPARTS (lhs_type)))
{
  error ("type mismatch in vector pack expression");
  debug_generic_expr (lhs_type);


Jakub


[PATCH] libgcov: report about a different timestamp (PR gcov-profile/85759).

2018-05-29 Thread Martin Liška
Hi.

As showed twice in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85759 it's 
quite problematic
when a profile data file is overwritten for a different compilation unit. I 
believe it's not
intentional in most cases and it deserves an error message in libgcov. 
Moreover, to be really
sure we don't break a profile, users should use GCOV_EXIT_AT_ERROR.

Tested on gcov.exp on x86_64-linux-gnu.

Ready to install after proper bootstrap?
Thanks,
Martin

gcc/ChangeLog:

2018-05-29  Martin Liska  

PR gcov-profile/85759
* doc/gcov.texi: Document GCOV_ERROR_FILE and GCOV_EXIT_AT_ERROR
env variables.

libgcc/ChangeLog:

2018-05-29  Martin Liska  

PR gcov-profile/85759
* libgcov-driver-system.c (gcov_error): Introduce usage of
GCOV_EXIT_AT_ERROR env. variable.
* libgcov-driver.c (merge_one_data): Print error that we
overwrite a gcov file with a different timestamp.
---
 gcc/doc/gcov.texi  |  8 
 libgcc/libgcov-driver-system.c | 10 +-
 libgcc/libgcov-driver.c|  8 ++--
 3 files changed, 23 insertions(+), 3 deletions(-)


diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index 4bd976db0b5..1cdca118b45 100644
--- a/gcc/doc/gcov.texi
+++ b/gcc/doc/gcov.texi
@@ -801,6 +801,14 @@ as well as handlers registered with @code{atexit}.
 If an executable loads a dynamic shared object via dlopen functionality,
 @option{-Wl,--dynamic-list-data} is needed to dump all profile data.
 
+Profiling run-time library reports various errors related to profile
+manipulation and profile saving.  Errors are printed into standard error output
+or @samp{GCOV_ERROR_FILE} file, if environment variable is used.
+In order to terminate immediately after an errors occurs
+set @samp{GCOV_EXIT_AT_ERROR} environment variable.
+That can help users to find profile clashing which leads
+to a misleading profile.
+
 @c man end
 
 @node Gcov Data Files
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 0df44239363..bf125869dc0 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -62,8 +62,16 @@ gcov_error (const char *fmt, ...)
   va_list argp;
 
   va_start (argp, fmt);
-  ret = vfprintf (get_gcov_error_file (), fmt, argp);
+  FILE *f = get_gcov_error_file ();
+  ret = vfprintf (f, fmt, argp);
   va_end (argp);
+
+  if (getenv ("GCOV_EXIT_AT_ERROR"))
+{
+  fprintf (f, "profiling:exiting after an error\n");
+  exit (1);
+}
+
   return ret;
 }
 
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index b4f195b8259..610356383f1 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -372,8 +372,12 @@ merge_one_data (const char *filename,
 
   length = gcov_read_unsigned ();
   if (length != gi_ptr->stamp)
-/* Read from a different compilation. Overwrite the file.  */
-return 0;
+{
+  /* Read from a different compilation.  Overwrite the file.  */
+  gcov_error ("profiling:%s:overwriting an existing profile data "
+		  "with a different timestamp\n", filename);
+  return 0;
+}
 
   /* Look for program summary.  */
   for (f_ix = 0;;)



Re: [PATCH] Introduce VEC_UNPACK_FIX_TRUNC_{LO,HI}_EXPR and VEC_PACK_FLOAT_EXPR, use it in x86 vectorization (PR target/85918)

2018-05-29 Thread Richard Biener
On Tue, 29 May 2018, Jakub Jelinek wrote:

> On Mon, May 28, 2018 at 12:12:18PM +0200, Richard Biener wrote:
> > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> > 
> > Apart from
> > 
> > --- gcc/tree-cfg.c.jj   2018-05-26 23:03:55.361873297 +0200
> > +++ gcc/tree-cfg.c  2018-05-27 12:54:55.046197128 +0200
> > @@ -3676,6 +3676,8 @@ verify_gimple_assign_unary (gassign *stm
> >  case VEC_UNPACK_LO_EXPR:
> >  case VEC_UNPACK_FLOAT_HI_EXPR:
> >  case VEC_UNPACK_FLOAT_LO_EXPR:
> > +case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
> > +case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
> >/* FIXME.  */
> >return false;
> >  
> > 
> > the middle-end changes look OK.  Can you please add verification
> > for the new codes here?
> 
> So like this (incremental patch, as it affects also the other codes)?
> 
> The VECTOR_BOOLEAN_P stuff is there because apparently we use these codes on
> vector booleans too where the element size is the same (for
> VEC_UNPACK_{HI,LO}_EXPR only).
> 
> Also, not really sure how to verify sizes of the whole vectors or better
> nunits in the world of poly-int vector sizes (but VEC_PACK_*EXPR doesn't
> verify that either).

Looking at other examples the only thing we have is
maybe_ne and friends on TYPE_VECTOR_SUBPARTS.  But I think the only
thing missing is

 || (maybe_ne (TYPE_VECTOR_SUBPARTS (lhs_type),
   2 * TYPE_VECTOR_SUBPARTS (rhs_type)))

that together with the mode size check should ensure same size
vectors.

Ok with this adjustment.

Thanks,
Richard.

> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2018-05-29  Jakub Jelinek  
> 
>   * tree-cfg.c (verify_gimple_assign_unary): Add checking for
>   VEC_UNPACK_*_EXPR.
> 
> --- gcc/tree-cfg.c.jj 2018-05-28 19:47:55.180685259 +0200
> +++ gcc/tree-cfg.c2018-05-29 10:05:55.213775216 +0200
> @@ -3678,7 +3678,35 @@ verify_gimple_assign_unary (gassign *stm
>  case VEC_UNPACK_FLOAT_LO_EXPR:
>  case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
>  case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
> -  /* FIXME.  */
> +  if (TREE_CODE (rhs1_type) != VECTOR_TYPE
> +  || TREE_CODE (lhs_type) != VECTOR_TYPE
> +  || (!INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
> +   && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type)))
> +  || (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
> +   && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type)))
> +   || ((rhs_code == VEC_UNPACK_HI_EXPR
> +|| rhs_code == VEC_UNPACK_LO_EXPR)
> +   && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
> +   != INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type
> +   || ((rhs_code == VEC_UNPACK_FLOAT_HI_EXPR
> +|| rhs_code == VEC_UNPACK_FLOAT_LO_EXPR)
> +   && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
> +   || SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type
> +   || ((rhs_code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
> +|| rhs_code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
> +   && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
> +   || SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type
> +   || (maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
> + 2 * GET_MODE_SIZE (element_mode (rhs1_type)))
> +   && (!VECTOR_BOOLEAN_TYPE_P (lhs_type)
> +   || !VECTOR_BOOLEAN_TYPE_P (rhs1_type
> + {
> +   error ("type mismatch in vector unpack expression");
> +   debug_generic_expr (lhs_type);
> +   debug_generic_expr (rhs1_type);
> +   return true;
> +}
> +
>return false;
>  
>  case NEGATE_EXPR:
> 
> 
>   Jakub
> 
> 

-- 
Richard Biener 
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)


[C++ PATCH] Avoid bogus -Wunused-but-set* with structured binding (PR c++/85952)

2018-05-29 Thread Jakub Jelinek
Hi!

Initializing the decomposition temporary from an expression with array type
is a special aggregate initialization path in which we wouldn't mark the
expression as read for the purposes of -Wunused-but-set*.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2018-05-29  Jakub Jelinek  

PR c++/85952
* init.c (build_aggr_init): For structured binding initialized from
array call mark_rvalue_use on the initializer.

* g++.dg/warn/Wunused-var-33.C: New test.

--- gcc/cp/init.c.jj2018-05-25 14:34:41.0 +0200
+++ gcc/cp/init.c   2018-05-28 19:04:10.504063972 +0200
@@ -1678,6 +1678,7 @@ build_aggr_init (tree exp, tree init, in
   if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
{
  from_array = 1;
+ init = mark_rvalue_use (init);
  if (init && DECL_P (init)
  && !(flags & LOOKUP_ONLYCONVERTING))
{
--- gcc/testsuite/g++.dg/warn/Wunused-var-33.C.jj   2018-05-28 
19:32:00.236440573 +0200
+++ gcc/testsuite/g++.dg/warn/Wunused-var-33.C  2018-05-28 19:31:11.816372827 
+0200
@@ -0,0 +1,29 @@
+// PR c++/85952
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wunused-but-set-variable" }
+
+int
+foo ()
+{
+  int a[2] = {1, 2};   // { dg-bogus "set but not used" } */
+  auto [x, y] = a; // { dg-warning "structured bindings only available 
with" "" { target c++14_down } }
+  return x + y;
+}
+
+struct S { int d, e; };
+
+int
+bar ()
+{
+  S a = {1, 2};
+  auto [x, y] = a; // { dg-warning "structured bindings only available 
with" "" { target c++14_down } }
+  return x + y;
+}
+
+int
+baz ()
+{
+  S a = {1, 2};
+  auto & [x, y] = a;   // { dg-warning "structured bindings only available 
with" "" { target c++14_down } }
+  return x + y;
+}

Jakub


Re: [PATCH] Fix doc/invoke.texi ARM buglet

2018-05-29 Thread Kyrill Tkachov



On 28/05/18 11:22, Jakub Jelinek wrote:

Hi!

I've noticed
../../gcc/doc/invoke.texi:15971: warning: @itemx should not begin @table
errors, fixed thusly, committed as obvious to trunk.
Probably it needs backporting too.



Thanks Jakub.
That is caused by my oversight in r260362 when I removed the first @item
in that list. So it wouldn't need fixing on the branches.

Thanks for fixing this.
Kyrill


2018-05-28  Jakub Jelinek  

* doc/invoke.texi (ARM Options): Use @item instead of @itemx
for armv5te.

--- gcc/doc/invoke.texi.jj  2018-05-25 14:34:35.589376306 +0200
+++ gcc/doc/invoke.texi 2018-05-28 12:11:59.028679696 +0200
@@ -15968,7 +15968,7 @@ The table below lists the supported exte
 Architectures not mentioned do not support any extensions.

 @table @samp
-@itemx armv5te
+@item armv5te
 @itemx armv6
 @itemx armv6j
 @itemx armv6k


Jakub




[PATCH] Fix lower-subreg ICE (PR target/85945)

2018-05-29 Thread Jakub Jelinek
Hi!

We ICE on the following testcase, because lower-subreg sees only
SFmode subregs of a multi-word pseudo (V4SFmode) and decides to decompose
it.  Decomposition is done through replacing the multi-word pseudo with
a concat of word-sized integer pseudos; unfortunately, we don't allow
SFmode subregs of DImode inner regs (or any other mix of floating and
integral mode where the sizes aren't the same), so we ICE later on during
the lower-subreg pass.

The following patch punts in that case, unless the size is the same
(i.e. allows SFmode on 32-bit word targets or DFmode on 64-bit word ones).

Bootstrapped/regtested on x86_64-linux and i686-linux plus tested with a
cross to s390x-linux on the testcase.  Ok for trunk?

BTW, wonder if we also shouldn't punt in case the inner mode is vector mode,
I don't think it is desirable to undo vectorization this way (but would like
to try that as a separate patch and gather some statistics).

For this patch I've gathered statistics too, on x86_64/i686-linux this patch
changes behavior in a couple of 64-bit gcc.target/i386/ tests where the
modes in all cases were SFmode (outer) and V4SFmode (inner), but it seems at
least on avx5124fmadd-v4fnmaddss-1.c I've looked at we in the end didn't
decide to decompose it anyway (perhaps some other non-subreg use).

2018-05-29  Jakub Jelinek  

PR target/85945
* lower-subreg.c (find_decomposable_subregs): Don't decompose float
subregs of multi-word pseudos unless the float mode has word size.

* gcc.c-torture/compile/pr85945.c: New test.

--- gcc/lower-subreg.c.jj   2018-01-04 00:43:17.209703103 +0100
+++ gcc/lower-subreg.c  2018-05-28 16:52:48.078871856 +0200
@@ -497,7 +497,16 @@ find_decomposable_subregs (rtx *loc, enu
 were the same number and size of pieces.  Hopefully this
 doesn't happen much.  */
 
- if (outer_words == 1 && inner_words > 1)
+ if (outer_words == 1
+ && inner_words > 1
+ /* Don't allow to decompose floating point subregs of
+multi-word pseudos if the floating point mode does
+not have word size, because otherwise we'd generate
+a subreg with that floating mode from a different
+sized integral pseudo which is not allowed by
+validate_subreg.  */
+ && (!FLOAT_MODE_P (GET_MODE (x))
+ || outer_size == UNITS_PER_WORD))
{
  bitmap_set_bit (decomposable_context, regno);
  iter.skip_subrtxes ();
--- gcc/testsuite/gcc.c-torture/compile/pr85945.c.jj2018-05-28 
18:26:28.043765766 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr85945.c   2018-05-28 
18:24:23.274594221 +0200
@@ -0,0 +1,16 @@
+/* PR target/85945 */
+
+typedef float V __attribute__((vector_size(16)));
+union U { V v; float f[4]; };
+int f;
+float g[4];
+
+void
+foo (void)
+{
+  V d;
+  union U i;
+  i.v = d;
+  for (f = 0; f < 4; f++)
+g[f] = i.f[f];
+}

Jakub


Re: [PATCH] Introduce VEC_UNPACK_FIX_TRUNC_{LO,HI}_EXPR and VEC_PACK_FLOAT_EXPR, use it in x86 vectorization (PR target/85918)

2018-05-29 Thread Jakub Jelinek
On Mon, May 28, 2018 at 12:12:18PM +0200, Richard Biener wrote:
> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> Apart from
> 
> --- gcc/tree-cfg.c.jj   2018-05-26 23:03:55.361873297 +0200
> +++ gcc/tree-cfg.c  2018-05-27 12:54:55.046197128 +0200
> @@ -3676,6 +3676,8 @@ verify_gimple_assign_unary (gassign *stm
>  case VEC_UNPACK_LO_EXPR:
>  case VEC_UNPACK_FLOAT_HI_EXPR:
>  case VEC_UNPACK_FLOAT_LO_EXPR:
> +case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
> +case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
>/* FIXME.  */
>return false;
>  
> 
> the middle-end changes look OK.  Can you please add verification
> for the new codes here?

So like this (incremental patch, as it affects also the other codes)?

The VECTOR_BOOLEAN_P stuff is there because apparently we use these codes on
vector booleans too where the element size is the same (for
VEC_UNPACK_{HI,LO}_EXPR only).

Also, not really sure how to verify sizes of the whole vectors or better
nunits in the world of poly-int vector sizes (but VEC_PACK_*EXPR doesn't
verify that either).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-05-29  Jakub Jelinek  

* tree-cfg.c (verify_gimple_assign_unary): Add checking for
VEC_UNPACK_*_EXPR.

--- gcc/tree-cfg.c.jj   2018-05-28 19:47:55.180685259 +0200
+++ gcc/tree-cfg.c  2018-05-29 10:05:55.213775216 +0200
@@ -3678,7 +3678,35 @@ verify_gimple_assign_unary (gassign *stm
 case VEC_UNPACK_FLOAT_LO_EXPR:
 case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
 case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
-  /* FIXME.  */
+  if (TREE_CODE (rhs1_type) != VECTOR_TYPE
+  || TREE_CODE (lhs_type) != VECTOR_TYPE
+  || (!INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
+ && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type)))
+  || (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
+ && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type)))
+ || ((rhs_code == VEC_UNPACK_HI_EXPR
+  || rhs_code == VEC_UNPACK_LO_EXPR)
+ && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
+ != INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type
+ || ((rhs_code == VEC_UNPACK_FLOAT_HI_EXPR
+  || rhs_code == VEC_UNPACK_FLOAT_LO_EXPR)
+ && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
+ || SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type
+ || ((rhs_code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
+  || rhs_code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
+ && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
+ || SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type
+ || (maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
+   2 * GET_MODE_SIZE (element_mode (rhs1_type)))
+ && (!VECTOR_BOOLEAN_TYPE_P (lhs_type)
+ || !VECTOR_BOOLEAN_TYPE_P (rhs1_type
+   {
+ error ("type mismatch in vector unpack expression");
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ return true;
+}
+
   return false;
 
 case NEGATE_EXPR:


Jakub


[testsuite, commited] Fix "too few/many" error messages in scan-*-times procs

2018-05-29 Thread Tom de Vries
Hi,

consider complex-6.c, that passes as:
...
PASS: gcc.dg/complex-6.c (test for excess errors)
PASS: gcc.dg/complex-6.c scan-tree-dump-times cplxlower1 "unord" 1
PASS: gcc.dg/complex-6.c scan-tree-dump-times cplxlower1 "__mulsc3" 1
...

If we drop one argument from the first scan-tree-dump-times:
...
-/* { dg-final { scan-tree-dump-times "unord" 1 "cplxlower1" } } */
+/* { dg-final { scan-tree-dump-times "unord" 1 } } */
...

we get:
...
PASS: gcc.dg/complex-6.c (test for excess errors)
ERROR: gcc.dg/complex-6.c: error executing dg-final: scan-tree-dump: too few 
arguments
UNRESOLVED: gcc.dg/complex-6.c: error executing dg-final: scan-tree-dump: too 
few arguments
...

while I would expect 'scan-tree-dump-times' to be used in the error message,
like this:
...
PASS: gcc.dg/complex-6.c (test for excess errors)
ERROR: gcc.dg/complex-6.c: error executing dg-final: scan-tree-dump-times: too 
few arguments
UNRESOLVED: gcc.dg/complex-6.c: error executing dg-final: scan-tree-dump-times: 
too few arguments
...

This patch fixes that for scan-{assembler,ipa,rtl,tree}-times.

Committed as obvious.

Thanks,
- Tom

[testsuite] Fix "too few/many" error messages in scan-*-times procs

2018-05-21  Tom de Vries  

* lib/scanasm.exp (scan-assembler-times): Use proc name in error
message.
* lib/scanipa.exp (scan-ipa-dump-times): Same.
* lib/scanrtl.exp (scan-rtl-dump-times): Same.
* lib/scantree.exp (scan-tree-dump-times): Same.

---
 gcc/testsuite/lib/scanasm.exp  | 4 ++--
 gcc/testsuite/lib/scanipa.exp  | 4 ++--
 gcc/testsuite/lib/scanrtl.exp  | 4 ++--
 gcc/testsuite/lib/scantree.exp | 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index 701e1f6..ad964fb 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -229,11 +229,11 @@ proc scan-ada-spec-not { args } {
 # Call pass if pattern is present given number of times, otherwise fail.
 proc scan-assembler-times { args } {
 if { [llength $args] < 2 } {
-   error "scan-assembler: too few arguments"
+   error "scan-assembler-times: too few arguments"
 return
 }
 if { [llength $args] > 3 } {
-   error "scan-assembler: too many arguments"
+   error "scan-assembler-times: too many arguments"
return
 }
 if { [llength $args] >= 3 } {
diff --git a/gcc/testsuite/lib/scanipa.exp b/gcc/testsuite/lib/scanipa.exp
index 68f1ae3..56c82c5 100644
--- a/gcc/testsuite/lib/scanipa.exp
+++ b/gcc/testsuite/lib/scanipa.exp
@@ -52,11 +52,11 @@ proc scan-ipa-dump { args } {
 proc scan-ipa-dump-times { args } {
 
 if { [llength $args] < 3 } {
-   error "scan-ipa-dump: too few arguments"
+   error "scan-ipa-dump-times: too few arguments"
return
 }
 if { [llength $args] > 4 } {
-   error "scan-ipa-dump: too many arguments"
+   error "scan-ipa-dump-times: too many arguments"
return
 }
 if { [llength $args] >= 4 } {
diff --git a/gcc/testsuite/lib/scanrtl.exp b/gcc/testsuite/lib/scanrtl.exp
index d744e7d..a24d005 100644
--- a/gcc/testsuite/lib/scanrtl.exp
+++ b/gcc/testsuite/lib/scanrtl.exp
@@ -54,11 +54,11 @@ force_conventional_output_for scan-rtl-dump
 proc scan-rtl-dump-times { args } {
 
 if { [llength $args] < 3 } {
-   error "scan-rtl-dump: too few arguments"
+   error "scan-rtl-dump-times: too few arguments"
return
 }
 if { [llength $args] > 4 } {
-   error "scan-rtl-dump: too many arguments"
+   error "scan-rtl-dump-times: too many arguments"
return
 }
 if { [llength $args] >= 4 } {
diff --git a/gcc/testsuite/lib/scantree.exp b/gcc/testsuite/lib/scantree.exp
index e66337a..d827190 100644
--- a/gcc/testsuite/lib/scantree.exp
+++ b/gcc/testsuite/lib/scantree.exp
@@ -52,11 +52,11 @@ proc scan-tree-dump { args } {
 proc scan-tree-dump-times { args } {
 
 if { [llength $args] < 3 } {
-   error "scan-tree-dump: too few arguments"
+   error "scan-tree-dump-times: too few arguments"
return
 }
 if { [llength $args] > 4 } {
-   error "scan-tree-dump: too many arguments"
+   error "scan-tree-dump-times: too many arguments"
return
 }
 if { [llength $args] >= 4 } {


[testsuite, commited] Use correct proc names in scanasm.exp

2018-05-29 Thread Tom de Vries
Hi,

Consider stack-usage-1.c, which passes with:
...
PASS: gcc.dg/stack-usage-1.c (test for excess errors)
PASS: gcc.dg/stack-usage-1.c scan-file foo\t(256|264)\tstatic
...

The dg-final directive scan-file is actually not used in the source file,
instead it's scan-stack-usage:
...
/* { dg-final { scan-stack-usage "foo\t\(256|264\)\tstatic" } } */
...

so we would expect:
...
PASS: gcc.dg/stack-usage-1.c (test for excess errors)
PASS: gcc.dg/stack-usage-1.c scan-stack-usage foo\t(256|264)\tstatic
...

This patch fixes scan-stack-usage, scan-stack-usage-not, scan-ada-spec,
scan-ada-spec-not and scan-lto-assembler.

Committed as obvious.

Thanks,
- Tom

[testsuite] Use correct proc names in scanasm.exp

2018-05-21  Tom de Vries  

* lib/scanasm.exp (scan-stack-usage, scan-stack-usage-not)
(scan-ada-spec, scan-ada-spec-not, scan-lto-assembler):
Use proc name as first argument to dg-scan.

---
 gcc/testsuite/lib/scanasm.exp | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index 5c574d5..701e1f6 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -179,7 +179,7 @@ proc scan-stack-usage { args } {
 set filename [lindex $testcase 0]
 set output_file "[file rootname [file tail $filename]].su"
 
-dg-scan "scan-file" 1 $testcase $output_file $args
+dg-scan "scan-stack-usage" 1 $testcase $output_file $args
 }
 
 # Check that a pattern is not present in the .su file produced by the
@@ -191,7 +191,7 @@ proc scan-stack-usage-not { args } {
 set filename [lindex $testcase 0]
 set output_file "[file rootname [file tail $filename]].su"
 
-dg-scan "scan-file-not" 0 $testcase $output_file $args
+dg-scan "scan-stack-usage-not" 0 $testcase $output_file $args
 }
 
 # Return the filename of the Ada spec corresponding to the argument.
@@ -213,7 +213,7 @@ proc scan-ada-spec { args } {
 set testcase  [testname-for-summary]
 set output_file "[get_ada_spec_filename $testcase]"
 
-dg-scan "scan-file" 1 $testcase $output_file $args
+dg-scan "scan-ada-spec" 1 $testcase $output_file $args
 }
 
 # Check that a pattern is not present in the .ads file produced by the
@@ -223,7 +223,7 @@ proc scan-ada-spec-not { args } {
 set testcase  [testname-for-summary]
 set output_file "[get_ada_spec_filename $testcase]"
 
-dg-scan "scan-file-not" 0 $testcase $output_file $args
+dg-scan "scan-ada-spec-not" 0 $testcase $output_file $args
 }
 
 # Call pass if pattern is present given number of times, otherwise fail.
@@ -541,5 +541,5 @@ proc scan-lto-assembler { args } {
 set filename [lindex $testcase 0]
 set output_file "[file rootname [file tail $filename]].exe.ltrans0.s"
 verbose "output_file: $output_file"
-dg-scan "scan-assembler" 1 $testcase $output_file $args
+dg-scan "scan-lto-assembler" 1 $testcase $output_file $args
 }


[testsuite, commited] Fix error message in scan-hidden/scan-not-hidden

2018-05-29 Thread Tom de Vries
Hi,

consider test-case visibility-1.c:
...
/* Test visibility attribute on function definition. */
/* { dg-do compile } */
/* { dg-require-visibility "" } */
/* { dg-final { scan-hidden "foo" } } */

void
__attribute__((visibility ("hidden")))
foo()
{ }
...

which passes with:
...
PASS: gcc.dg/visibility-1.c (test for excess errors)
PASS: gcc.dg/visibility-1.c scan-hidden hidden[ \t_]*foo
...

If we drop the argument to scan-hidden:
...
-/* { dg-final { scan-hidden "foo" } } */
+/* { dg-final { scan-hidden } } */
...

we get:
...
PASS: gcc.dg/visibility-1.c (test for excess errors)
PASS: gcc.dg/visibility-1.c scan-hidden hidden[ \t_]*
...

while we want:
...
PASS: gcc.dg/visibility-1.c (test for excess errors)
ERROR: gcc.dg/visibility-1.c: error executing dg-final: scan-hidden: too few 
arguments
UNRESOLVED: gcc.dg/visibility-1.c: error executing dg-final: scan-hidden: too 
few arguments
...

The problem originates from the fact that scan-hidden uses
'set args [lreplace $args 0 0 ...]' also when '[llength $args] == 0', which
results in '[llength $args] == 1'.

This patch fixes that, both for scan-hidden and scan-not-hidden.

Committed as obvious.

Thanks,
- Tom

[testsuite] Fix error message in scan-hidden/scan-not-hidden

2018-05-21  Tom de Vries  

* lib/scanasm.exp (scan-hidden, scan-not-hidden): Handle being called
with no arguments.

---
 gcc/testsuite/lib/scanasm.exp | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index 61e0f3f..5c574d5 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -125,11 +125,13 @@ proc scan-hidden { args } {
 set filename [lindex $testcase 0]
 set output_file "[file rootname [file tail $filename]].s"
 
-set symbol [lindex $args 0]
+if { [llength $args] > 0 } {
+   set symbol [lindex $args 0]
 
-set hidden_scan [hidden-scan-for $symbol]
+   set hidden_scan [hidden-scan-for $symbol]
 
-set args [lreplace $args 0 0 "$hidden_scan"]
+   set args [lreplace $args 0 0 "$hidden_scan"]
+}
 
 dg-scan "scan-hidden" 1 $testcase $output_file $args
 }
@@ -143,10 +145,12 @@ proc scan-not-hidden { args } {
 set filename [lindex $testcase 0]
 set output_file "[file rootname [file tail $filename]].s"
 
-set symbol [lindex $args 0]
-set hidden_scan [hidden-scan-for $symbol]
+if { [llength $args] > 0 } {
+   set symbol [lindex $args 0]
+   set hidden_scan [hidden-scan-for $symbol]
 
-set args [lreplace $args 0 0 "$hidden_scan"]
+   set args [lreplace $args 0 0 "$hidden_scan"]
+}
 
 dg-scan "scan-not-hidden" 0 $testcase $output_file $args
 }