Re: [tree-tailcall] Check if function returns it's argument

2016-12-09 Thread Richard Biener
On Wed, 7 Dec 2016, Jeff Law wrote:

> On 12/06/2016 03:16 AM, Richard Biener wrote:
> > On Tue, 6 Dec 2016, Richard Biener wrote:
> > 
> > > On Mon, 5 Dec 2016, Jeff Law wrote:
> > > 
> > > > On 12/02/2016 01:33 AM, Richard Biener wrote:
> > > > > > The LHS on the assignment makes it easier to identify when a tail
> > > > > > call is
> > > > > > possible.  It's not needed for correctness.  Not having the LHS on
> > > > > > the
> > > > > > assignment just means we won't get an optimized tail call.
> > > > > > 
> > > > > > Under what circumstances would the LHS possibly be removed?  We know
> > > > > > the
> > > > > > return statement references the LHS, so it's not going to be
> > > > > > something
> > > > > > that
> > > > > > DCE will do.
> > > > > 
> > > > > Well, I thought Prathamesh added the optimization to copy-propagate
> > > > > the lhs from the returned argument.  So we'd have both transforms
> > > > > here.
> > > > That seems like a mistake -- the fact that we can copy propagate the LHS
> > > > from
> > > > the returned argument is interesting, but in practice I've found it to
> > > > not be
> > > > useful to do so.
> > > > 
> > > > The problem is it makes the value look live across a the call and we're
> > > > then
> > > > dependent upon the register allocator to know the trick about the
> > > > returned
> > > > argument value and apply it consistently -- which it does not last I
> > > > checked.
> > > > 
> > > > I think we're better off leaving the call in the form of LHS = call ()
> > > > if the
> > > > return value is used.  That's going to be more palatable to tail
> > > > calling.
> > > 
> > > Yes, that's something I also raised earlier in the thread.  Note that
> > > any kind of value-numbering probably wants to know the equivalence
> > > for simplifications but in the end wants to disable propagating the
> > > copy (in fact it should propagate the return value from the point of
> > > the call).  I suppose I know how to implement that in FRE/PRE given it has
> > > separate value-numbering and elimination phases.  Something for GCC 8.
> > 
> > The following does that (it shows we don't handle separating LHS
> > and overall stmt effect very well).  It optimizes a testcase like
> > 
> > void *foo (void *p, int c, __SIZE_TYPE__ n)
> > {
> >   void *q = __builtin_memset (p, c, n);
> >   if (q == p)
> > return p;
> >   return q;
> > }
> > 
> > to
> > 
> > foo (void * p, int c, long unsigned int n)
> > {
> >   void * q;
> > 
> >[0.0%]:
> >   q_7 = __builtin_memset (p_3(D), c_4(D), n_5(D));
> >   return q_7;
> > 
> > in early FRE.
> Yea.  Not sure how often something like that would happen in practice, but
> using the equivalence to simplify rather than for propagation seems like the
> way to go.
> 
> I keep thinking about doing some similar in DOM, but haven't gotten around to
> seeing what the fallout would be.

Shouldn't be too bad (it would require to keep an additional 
what-to-substitute-for-value-X lattice during the DOM walk).  But it
will still require some "magic" to decide about those conditional
equivalences... (I think).

Separating "values" from what we substitute during elimination is a good
thing in general, so we can be more aggressive with the value parts.


Re: [PATCH] Reassoc zero_one_operation fixes (PR tree-optimization/78726)

2016-12-09 Thread Richard Biener
On Thu, 8 Dec 2016, Jakub Jelinek wrote:

> Hi!
> 
> The following testcases show two bugs in zero_one_operation (used during
> undistribute optimization) and functions it calls.
> The first one (wrong-code) is fixed by the
> +  tree orig_def = *def;
> and
> -  if (stmts_to_fix.length () > 0)
> +  if (stmts_to_fix.length () > 0 || *def == orig_def)
> changes in zero_one_operation - e.g. in the testcase we have before reassoc
>   _6 = _5 * a_11;
>   _7 = _5 * _6;
> and call zero_one_operation for _7 with op a_11.  The last stmt isn't pushed
> into stmts_to_fix, the *def stmt is handled specially in
> make_new_ssa_for_all_defs.  And the previous one, while it is pushed, it is
> popped from there again, because the stmt is removed and instead _6 use
> is replaced with _5.  That changes what value _7 holds, so we want to use
> a new SSA_NAME for it (or deal with debug stmts and reset flow sensitive
> info etc.).
> 
> The second one is wrong-debug, make_new_ssa_for_def replaces the uses of old
> lhs with the new lhs (which is fine in the code uses, but for debug info
> because we zeroed out a_11 we want to say that previous uses of _7 are now
> the _7's replacement * a_11.  Which is what the rest of the patch does
> and there is a guality testcase that verifies it (previously it would fail).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2016-12-08  Jakub Jelinek  
> 
>   PR tree-optimization/78726
>   * tree-ssa-reassoc.c (make_new_ssa_for_def): Add OPCODE and OP
>   argument.  For lhs uses in debug stmts, don't replace lhs with
>   new_lhs, but with a debug temp set to new_lhs opcode op.
>   (make_new_ssa_for_all_defs): Add OPCODE argument, pass OPCODE and
>   OP down to make_new_ssa_for_def.
>   (zero_one_operation): Call make_new_ssa_for_all_defs even when
>   stmts_to_fix is empty, if *def has not changed yet.  Pass
>   OPCODE to make_new_ssa_for_all_defs.
> 
>   * gcc.c-torture/execute/pr78726.c: New test.
>   * gcc.dg/guality/pr78726.c: New test.
> 
> --- gcc/tree-ssa-reassoc.c.jj 2016-11-09 16:34:58.0 +0100
> +++ gcc/tree-ssa-reassoc.c2016-12-08 15:53:13.768894146 +0100
> @@ -1153,12 +1153,12 @@ decrement_power (gimple *stmt)
> SSA.  Also return the new SSA.  */
>  
>  static tree
> -make_new_ssa_for_def (gimple *stmt)
> +make_new_ssa_for_def (gimple *stmt, enum tree_code opcode, tree op)
>  {
>gimple *use_stmt;
>use_operand_p use;
>imm_use_iterator iter;
> -  tree new_lhs;
> +  tree new_lhs, new_debug_lhs = NULL_TREE;
>tree lhs = gimple_get_lhs (stmt);
>  
>new_lhs = make_ssa_name (TREE_TYPE (lhs));
> @@ -1167,8 +1167,28 @@ make_new_ssa_for_def (gimple *stmt)
>/* Also need to update GIMPLE_DEBUGs.  */
>FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
>  {
> +  tree repl = new_lhs;
> +  if (is_gimple_debug (use_stmt))
> + {
> +   if (new_debug_lhs == NULL_TREE)
> + {
> +   new_debug_lhs = make_node (DEBUG_EXPR_DECL);
> +   gdebug *def_temp
> + = gimple_build_debug_bind (new_debug_lhs,
> +build2 (opcode, TREE_TYPE (lhs),
> +new_lhs, op),
> +stmt);
> +   DECL_ARTIFICIAL (new_debug_lhs) = 1;
> +   TREE_TYPE (new_debug_lhs) = TREE_TYPE (lhs);
> +   SET_DECL_MODE (new_debug_lhs, TYPE_MODE (TREE_TYPE (lhs)));
> +   gimple_set_uid (def_temp, gimple_uid (stmt));
> +   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
> +   gsi_insert_after (&gsi, def_temp, GSI_SAME_STMT);
> + }
> +   repl = new_debug_lhs;
> + }
>FOR_EACH_IMM_USE_ON_STMT (use, iter)
> - SET_USE (use, new_lhs);
> + SET_USE (use, repl);
>update_stmt (use_stmt);
>  }
>return new_lhs;
> @@ -1179,7 +1199,7 @@ make_new_ssa_for_def (gimple *stmt)
> if *DEF is not OP.  */
>  
>  static void
> -make_new_ssa_for_all_defs (tree *def, tree op,
> +make_new_ssa_for_all_defs (tree *def, enum tree_code opcode, tree op,
>  vec &stmts_to_fix)
>  {
>unsigned i;
> @@ -1189,10 +1209,10 @@ make_new_ssa_for_all_defs (tree *def, tr
>&& TREE_CODE (*def) == SSA_NAME
>&& (stmt = SSA_NAME_DEF_STMT (*def))
>&& gimple_code (stmt) != GIMPLE_NOP)
> -*def = make_new_ssa_for_def (stmt);
> +*def = make_new_ssa_for_def (stmt, opcode, op);
>  
>FOR_EACH_VEC_ELT (stmts_to_fix, i, stmt)
> -make_new_ssa_for_def (stmt);
> +make_new_ssa_for_def (stmt, opcode, op);
>  }
>  
>  /* Find the single immediate use of STMT's LHS, and replace it
> @@ -1232,6 +1252,7 @@ propagate_op_to_single_use (tree op, gim
>  static void
>  zero_one_operation (tree *def, enum tree_code opcode, tree op)
>  {
> +  tree orig_def = *def;
>gimple *stmt = SSA_NAME_DEF_STMT (*def);
>/* PR72835 - Record the stmt chain that has 

Re: [PATCH] Add support for Fuchsia (OS)

2016-12-09 Thread Andrew Pinski
On Thu, Dec 8, 2016 at 2:55 PM, Josh Conner  wrote:
> This patch adds support to gcc for the Fuchsia OS
> (https://fuchsia.googlesource.com/).
>
> OK for mainline?

A few comments:
> +/* Build with PIC by default.  */
> +#undef  CC1_SPEC
> +#define CC1_SPEC "%{!fno-pic:%{!fno-PIC:%{!fpic:%{!fPIC: -fPIC"

Is it PIC by default or really PIE by default?
Also how does this interact with the -fpie/-fPIE options?

Thanks,
Andrew


>
> Thanks -
>
> Josh
>
>
> 2016-12-08  Joshua Conner  
>
>
> * config/arm/fuchsia-elf.h: New file.
>
> * config/fuchsia.h: New file.
>
> * config.gcc (*-*-fuchsia*): Set native_system_header_dir.
>
> (aarch64*-*-fuchsia*, arm*-*-fuchsia*, x86_64-*-fuchsia*): Add to
> targets.
>
> * config.host: (aarch64*-*-fuchsia*, arm*-*-fuchsia*): Add to hosts.
>
>


Re: [PR tree-optimization/67955] Exploit PTA in DSE

2016-12-09 Thread Richard Biener
On Wed, Dec 7, 2016 at 12:18 AM, Jeff Law  wrote:
>
>
> So I was going through the various DSE related bugs as stumbled across
> 67955.
>
> The basic issue in 67955 is that DSE is too simplistic when trying to
> determine if two writes hit the same memory address.  There are cases were
> PTA analysis can get us that information.
>
> The unfortunate problem is that PTA can generate a single points-to set for
> pointers to different elements in the same array.  So we can only exploit a
> special case.  Namely when we get a PTA singleton and the size of the store
> is the same size of the pointed-to object.
>
> That doesn't happen in a bootstrap, but it does happen for the testcase in
> the BZ as well as a handful of tests in the testsuite -- Tom reported 6
> unique tests where it triggered, I ran my own tests where two more were spit
> out.  Not huge.  But the cost is low.
>
> All that I've done with Tom's patch is update the call into the PTA system.
> It's very clearly Tom's work.
>
> Bootstrapped and regression tested on x86_64-linux-gnu.  Installing on the
> trunk.

Just double-checked it doesn't break

int foo (int *p, int b)
{
  int *q;
  int i = 1;
  if (b)
q = &i;
  else
q = (void *)0;
  *q = 2;
  return i;
}

with -fexceptions -fnon-call-exceptions.  More comments below.

> jeff
>
> commit cfc96cf6c8ea2c6e638123a93663964f6d78fb10
> Author: law 
> Date:   Tue Dec 6 23:18:17 2016 +
>
> PR tree-optimization/67955
> * tree-ssa-alias.c (same_addr_size_stores_p): New function.
> (stmt_kills_ref_p): Use it.
>
> PR tree-optimization/67955
> * gcc.dg/tree-ssa/dse-points-to.c: New test.
>
> git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243325
> 138bc75d-0d04-0410-961f-82ee72b054a4
>
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index 61eeea3..797b711 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,9 @@
> +2016-12-06  Tom de Vries  
> +
> +   PR tree-optimization/67955
> +   * tree-ssa-alias.c (same_addr_size_stores_p): New function.
> +   (stmt_kills_ref_p): Use it.
> +
>  2016-12-06  Eric Botcazou  
>
> PR middle-end/78700
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index 5adcdd2..6090a96 100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2016-12-06  Tom de Vries  
> +
> +   PR tree-optimization/67955
> +   * gcc.dg/tree-ssa/dse-points-to.c: New test.
> +
>  2016-12-06  Michael Meissner  
>
> PR target/78658
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c
> b/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c
> new file mode 100644
> index 000..8003556
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre
> -fno-tree-vrp" } */
> +/* { dg-additional-options "-fdump-tree-dse1-details" } */
> +
> +int
> +f ()
> +{
> +  int a;
> +  int *p = &a;
> +  *p = 1;
> +  a = 2;
> +  return a;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Deleted dead store.*p_1" 1 "dse1"} }
> */
> diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
> index 10f1677..37b581d 100644
> --- a/gcc/tree-ssa-alias.c
> +++ b/gcc/tree-ssa-alias.c
> @@ -2316,6 +2316,78 @@ stmt_may_clobber_ref_p (gimple *stmt, tree ref)
>return stmt_may_clobber_ref_p_1 (stmt, &r);
>  }
>
> +/* Return true if store1 and store2 described by corresponding tuples
> +have the same size and store to the same
> +   address.  */
> +
> +static bool
> +same_addr_size_stores_p (tree base1, HOST_WIDE_INT offset1, HOST_WIDE_INT
> size1,
> +HOST_WIDE_INT max_size1,
> +tree base2, HOST_WIDE_INT offset2, HOST_WIDE_INT
> size2,
> +HOST_WIDE_INT max_size2)
> +{
> +  /* For now, just handle VAR_DECL.  */

PARAM and RESULT_DECL (aka SSA_VAR_P) should be safe.

> +  bool base1_obj_p = VAR_P (base1);
> +  bool base2_obj_p = VAR_P (base2);
> +
> +  /* We need one object.  */
> +  if (base1_obj_p == base2_obj_p)
> +return false;
> +  tree obj = base1_obj_p ? base1 : base2;
> +
> +  /* And we need one MEM_REF.  */
> +  bool base1_memref_p = TREE_CODE (base1) == MEM_REF;
> +  bool base2_memref_p = TREE_CODE (base2) == MEM_REF;
> +  if (base1_memref_p == base2_memref_p)
> +return false;
> +  tree memref = base1_memref_p ? base1 : base2;
> +
> +  /* Sizes need to be valid.  */
> +  if (max_size1 == -1 || max_size2 == -1
> +  || size1 == -1 || size2 == -1)
> +return false;
> +
> +  /* Max_size needs to match size.  */
> +  if (max_size1 != size1
> +  || max_size2 != size2)
> +return false;
> +
> +  /* Sizes need to match.  */
> +  if (size1 != size2)
> +return false;
> +
> +  /* Offsets need to be 0.  */
> +  if (offset1 != 0
> +  || offset2 != 0)
> +return false;

These two checks should be done first IMHO.

> +  /* Check that memref is a store to pointer w

[Darwin, PPC] Fix PR71496 by marking pic base loads as non-copyable.

2016-12-09 Thread Iain Sandoe

Hi Segher,

Working through my backlog of Darwin patches …  this one is needed on trunk and 
6.x
(although it’s marked as rtl-optimization, it actually prevents bootstrap on 
the branch with
Java enabled).  Therefore, if possible, I’d like to get this in before the 6.3 
freeze.



The Darwin pic base loads (and reloads for non-local-gotos) are not validly
copied (since the pic base label would be duplicated).  Thus, this patch marks
them accordingly.

OK for trunk?
OK for GCC-6 branch?

thanks,
Iain

gcc/

2016-12-09  Iain Sandoe  

PR rtl-optimization/71496
* config/rs6000/darwin.md (load_macho_picbase_si): Mark as non-
copyable.  (load_macho_picbase_di, reload_macho_picbase_si,
reload_macho_picbase_di): Likewise.


---
 gcc/config/rs6000/darwin.md | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/config/rs6000/darwin.md b/gcc/config/rs6000/darwin.md
index 57ce30e..bae8b2b 100644
--- a/gcc/config/rs6000/darwin.md
+++ b/gcc/config/rs6000/darwin.md
@@ -265,6 +265,7 @@ You should have received a copy of the GNU General Public 
License
   return "bcl 20,31,%0\\n%0:";
 }
   [(set_attr "type" "branch")
+   (set_attr "cannot_copy" "yes")
(set_attr "length" "4")])
 
 (define_insn "load_macho_picbase_di"
@@ -281,6 +282,7 @@ You should have received a copy of the GNU General Public 
License
   return "bcl 20,31,%0\\n%0:";
 }
   [(set_attr "type" "branch")
+   (set_attr "cannot_copy" "yes")
(set_attr "length" "4")])
 
 (define_expand "macho_correct_pic"
@@ -416,6 +418,7 @@ You should have received a copy of the GNU General Public 
License
 return "bcl 20,31,%0\\n%0:";
 }
   [(set_attr "type" "branch")
+   (set_attr "cannot_copy" "yes")
(set_attr "length" "4")])
 
 (define_insn "reload_macho_picbase_di"
@@ -439,6 +442,7 @@ You should have received a copy of the GNU General Public 
License
 return "bcl 20,31,%0\\n%0:";
 }
   [(set_attr "type" "branch")
+   (set_attr "cannot_copy" "yes")
(set_attr "length" "4")])
 
 ;; We need to restore the PIC register, at the site of nonlocal label.
-- 
2.8.1




Re: Default associative containers constructors/destructor/assignment

2016-12-09 Thread Jonathan Wakely

On 08/12/16 21:40 +0100, François Dumont wrote:

On 06/12/2016 12:54, Jonathan Wakely wrote:

On 20/11/16 19:14 +0100, François Dumont wrote:
Talking about _M_color I just realize that move semantic doesn't 
copy _M_color. Shouldn't we capture it along with all the other 
_M_header information ?


Is it needed? I think the current code does the right thing, doesn't
it? I'd prefer not to change it without a testcase showing why we need
to.


I was hoping you knew it. So I kept it unchanged and will add to my 
TODO to check this.


I think it's OK already :-)


Committed now.


Thanks!



Re: libgo patch committed: Copy hash code from Go 1.7 runtime

2016-12-09 Thread Rainer Orth
Hi Ian,

> This patch to libgo copies the memory hashing code from the Go 1.7
> runtime.  This is particular important because we earlier copied the
> hashmap code from Go 1.7, and that changed hash table sizes from prime
> numbers to powers of two.  The memory hashing code used before this
> patch was fine for prime numbers but for powers of two tended to hash
> many values to the same bucket, making maps much much slower than they
> should be.
>
> I rewrote the AES hashing code from gc assembler to C code using
> intrinsics.  The resulting code generates the same hash code for the
> same input as the gc code--that doesn't matter as such, but testing it
> ensures that the C code does something useful.
>
> I changed mips64pe32le to mips64p32le in configure script--noticed
> during CL review.
>
> Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu, both with
> and without the AES hashing code.  Committed to mainline.

this broke Solaris in two different ways:

* On both sparc and x86, libgo fails to compile:

In file included from /vol/gcc/src/hg/trunk/local/libgo/runtime/runtime.h:114:0,
 from /vol/gcc/src/hg/trunk/local/libgo/runtime/aeshash.c:7:
./runtime.inc:8:12: error: expected identifier or '(' before numeric constant
 #define m1 3168982561
^
./runtime.inc:782:11: note: in expansion of macro 'm1'
  uint32_t m1;
   ^~
./runtime.inc:9:12: error: expected identifier or '(' before numeric constant
 #define m2 3339683297
^
./runtime.inc:783:11: note: in expansion of macro 'm2'
  uint32_t m2;
   ^~
./runtime.inc:10:12: error: expected identifier or '(' before numeric constant
 #define m3 832293441
^
./runtime.inc:784:11: note: in expansion of macro 'm3'
  uint32_t m3;
   ^~
./runtime.inc:11:12: error: expected identifier or '(' before numeric constant
 #define m4 2336365089
^
./runtime.inc:785:11: note: in expansion of macro 'm4'
  uint32_t m4;
   ^~

  This is similar to what we had with c[01] before, and fixed in the
  same way:

# HG changeset patch
# Parent  b803ae8e678ea6de73d9892aad7b4b33740ae81a
Fix runtime/aeshash.c on Solaris

diff --git a/libgo/Makefile.am b/libgo/Makefile.am
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -561,7 +561,7 @@ s-sigtab: $(srcdir)/mksigtab.sh gen-sysi
 runtime.inc: s-runtime-inc; @true
 s-runtime-inc: runtime.lo Makefile
 	rm -f runtime.inc.tmp2
-	grep -v "#define _" runtime.inc.tmp | grep -v "#define c[01] " > runtime.inc.tmp2
+	grep -v "#define _" runtime.inc.tmp | grep -v "#define c[01] " | grep -v "#define m[1-4] " > runtime.inc.tmp2
 	for pattern in '_[GP][a-z]' _Max _Lock _Sig _Trace _MHeap _Num; do \
 	  grep "#define $$pattern" runtime.inc.tmp >> runtime.inc.tmp2; \
 	done

* Once the build completes, on Solaris/x86 with /bin/as every single Go
  execution test FAILs:

ld.so.1: a.out: fatal: 
/var/gcc/regression/trunk/12-gcc/build/i386-pc-solaris2.12/libgo/.libs/libgo.so.10:
 hardware capability (CA_SUNW_HW_1) unsupported: 0x440  [ AES SSSE3 ]
/vol/gcc/src/hg/trunk/local/libgo/testsuite/gotest[638]: wait: 19831: Killed
/vol/gcc/src/hg/trunk/local/libgo/testsuite/gotest[643]: wait: 19832: Terminated
/bin/ksh: 9035: Killed
FAIL: bufio

ld.so.1: array-1.x: fatal: 
/var/gcc/regression/trunk/12-gcc/build/i386-pc-solaris2.12/./libgo/.libs/libgo.so.10:
 hardware capability (CA_SUNW_HW_1) unsupported: 0x440  [ AES SSSE3 ]
FAIL: go.go-torture/execute/array-1.go execution,  -O0

  Again, this is a known issue, previously in libitm and recently in
  libgfortran.  The latter is fixed by my (still unreviewed) patch

https://gcc.gnu.org/ml/gcc-patches/2016-12/msg00336.html

  and can be fixed for libgo along the same lines (on top of the
  libgfortran etc. one):

2016-12-09  Rainer Orth  

* configure.ac: Call GCC_CHECK_LINKER_HWCAP.
* Makefile.am (AM_LDFLAGS): Initialize to HWCAP_LDFLAGS.
[USING_SPLIT_STACK]: Add to AM_LDFLAGS.
* aclocal.m4: Regenerate.
* configure: Regenerate.
* Makefile.in: Regenerate.
* testsuite/Makefile.in: Regenerate.

# HG changeset patch
# Parent  b803ae8e678ea6de73d9892aad7b4b33740ae81a
Disable hwcaps on libgo

diff --git a/libgo/Makefile.am b/libgo/Makefile.am
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -46,8 +46,10 @@ AM_CFLAGS = -fexceptions -fnon-call-exce
 	-I $(srcdir)/../libgcc -I $(srcdir)/../libbacktrace \
 	-I $(MULTIBUILDTOP)../../gcc/include
 
+AM_LDFLAGS = $(HWCAP_LDFLAGS)
+
 if USING_SPLIT_STACK
-AM_LDFLAGS = -XCClinker $(SPLIT_STACK)
+AM_LDFLAGS += -XCClinker $(SPLIT_STACK)
 endif
 
 # Multilib support.
diff --git a/libgo/configure.ac b/libgo/configure.ac
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -430,6 +430,9 @@ case "$target" in
 esac
 AC_SUBST(OSLDFLAGS)
 
+dnl Check linker hardware capability support.
+GCC_CHECK_LINKER_HWCAP
+
 dnl Use -fsplit-stack when compiling C code if available.
 AC_CACHE_CHECK([whether -fsplit-stack is supporte

[PATCH, testsuite] MIPS: Upgrade to R2 for -mnan=2008 and -mabs=2008.

2016-12-09 Thread Toma Tabacu
Hi,

The -mnan=2008 and -mabs=2008 options are not supported on pre-R2 targets.
This results in failures for tests which use these options, such as nan-2008.c,
fabs-2008.c etc.

This patch makes the testsuite upgrade to R2 if -mnan=2008 and -mabs=2008 are
used as test options.

Tested with mips-mti-elf.

Regards,
Toma Tabacu

gcc/testsuite/ChangeLog:

* gcc.target/mips/mips.exp (mips-dg-options): Upgrade to R2 for
-mnan=2008 and -mabs=2008.

diff --git a/gcc/testsuite/gcc.target/mips/mips.exp 
b/gcc/testsuite/gcc.target/mips/mips.exp
index c0b9680..3d04d2f 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -1145,7 +1145,9 @@ proc mips-dg-options { args } {
 || [mips_have_test_option_p options "HAS_INS"]
 || [mips_have_test_option_p options "HAS_MADD"]
 || [mips_have_test_option_p options "HAS_MADDPS"]
-|| [mips_have_test_option_p options "-mdspr2"]) } {
+|| [mips_have_test_option_p options "-mdspr2"]
+|| [mips_have_test_option_p options "-mnan=2008"]
+|| [mips_have_test_option_p options "-mabs=2008"]) } {
if { $gp_size == 32 } {
mips_make_test_option options "-mips32r2"
} else {


[PATCH][GCC 5] Fix PR78731

2016-12-09 Thread Richard Biener

The following fixes a jump-threading bug when threading through a backedge
(thus it's only applicable to GCC 5).  The issue is that when we see
a backedge walking the SSA value chain might end up picking up values
from a previous iteration.

The fix is to add backedge_seen to yet another function and avoid
walking the SSA value chain in that case.

Bootstrapped and tested on x86_64-unknown-linux-gnu - ok for the branch?

(I was sitting on this patch for some months because I only had a
proprietary testcase)

Thanks,
Richard.

2016-12-09  Richard Biener  

PR tree-optimization/78731
* tree-ssa-threadedge.c (simplify_control_stmt_condition):
If we've seen a backedge to not walk the SSA value chain.
(thread_around_empty_blocks): Pass down whether we've seen
a backedge to simplify_control_stmt_condition.
(thread_through_normal_block): Likewise.

* gcc.dg/torture/pr78731.c: New testcase.

Index: gcc/tree-ssa-threadedge.c
===
--- gcc/tree-ssa-threadedge.c   (revision 237797)
+++ gcc/tree-ssa-threadedge.c   (working copy)
@@ -574,7 +574,8 @@ simplify_control_stmt_condition (edge e,
 gimple stmt,
 gcond *dummy_cond,
 tree (*simplify) (gimple, gimple),
-bool handle_dominating_asserts)
+bool handle_dominating_asserts,
+bool backedge_seen)
 {
   tree cond, cached_lhs;
   enum gimple_code code = gimple_code (stmt);
@@ -593,7 +594,7 @@ simplify_control_stmt_condition (edge e,
   /* Get the current value of both operands.  */
   if (TREE_CODE (op0) == SSA_NAME)
{
- for (int i = 0; i < 2; i++)
+ for (int i = 0; i < (backedge_seen ? 1 : 2); i++)
{
  if (TREE_CODE (op0) == SSA_NAME
  && SSA_NAME_VALUE (op0))
@@ -605,7 +606,7 @@ simplify_control_stmt_condition (edge e,
 
   if (TREE_CODE (op1) == SSA_NAME)
{
- for (int i = 0; i < 2; i++)
+ for (int i = 0; i < (backedge_seen ? 1 : 2); i++)
{
  if (TREE_CODE (op1) == SSA_NAME
  && SSA_NAME_VALUE (op1))
@@ -689,7 +690,7 @@ simplify_control_stmt_condition (edge e,
 a loop invariant SSA_NAME used in the condition.  */
   if (cached_lhs)
{
- for (int i = 0; i < 2; i++)
+ for (int i = 0; i < (backedge_seen ? 1 : 2); i++)
{
  if (TREE_CODE (cached_lhs) == SSA_NAME
  && SSA_NAME_VALUE (cached_lhs))
@@ -940,7 +941,8 @@ thread_around_empty_blocks (edge taken_e
 
   /* Extract and simplify the condition.  */
   cond = simplify_control_stmt_condition (taken_edge, stmt, dummy_cond,
- simplify, handle_dominating_asserts);
+ simplify, handle_dominating_asserts,
+ *backedge_seen_p);
 
   /* If the condition can be statically computed and we have not already
  visited the destination edge, then add the taken edge to our thread
@@ -1326,7 +1328,8 @@ thread_through_normal_block (edge e,
 
   /* Extract and simplify the condition.  */
   cond = simplify_control_stmt_condition (e, stmt, dummy_cond, simplify,
- handle_dominating_asserts);
+ handle_dominating_asserts,
+ *backedge_seen_p);
 
   if (!cond)
return 0;
Index: gcc/testsuite/gcc.dg/torture/pr78731.c
===
--- gcc/testsuite/gcc.dg/torture/pr78731.c  (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr78731.c  (working copy)
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+
+#include 
+#include 
+
+#define GENERAL 1
+#define BRACKETS 2
+#define QUOTES 3
+
+void __attribute__((noinline,noclone))
+foo(char *qb, char* into)
+{
+  int state = QUOTES;
+  int save_state = BRACKETS;
+
+  while (qb)
+{
+  switch (state)
+   {
+   case BRACKETS:
+ exit(0);
+   case GENERAL:
+ abort ();
+   case QUOTES:
+ state = save_state;
+ save_state = GENERAL;
+ break;
+   default: ;
+   }
+  printf("State %d btw GENERAL %d\n", state, GENERAL);
+}
+  abort ();
+}
+
+int main()
+{
+  char *b = "123";
+  char out[4];
+  foo(b, out);
+  return 0;
+}


Re: [Darwin, PPC] Fix PR71496 by marking pic base loads as non-copyable.

2016-12-09 Thread Segher Boessenkool
Hi Iain,

On Fri, Dec 09, 2016 at 08:45:11AM +, Iain Sandoe wrote:
> The Darwin pic base loads (and reloads for non-local-gotos) are not validly
> copied (since the pic base label would be duplicated).  Thus, this patch marks
> them accordingly.
> 
> OK for trunk?
> OK for GCC-6 branch?

Okay for both.  Thanks,


Segher


> 2016-12-09  Iain Sandoe  
> 
>   PR rtl-optimization/71496
>   * config/rs6000/darwin.md (load_macho_picbase_si): Mark as non-
>   copyable.  (load_macho_picbase_di, reload_macho_picbase_si,
>   reload_macho_picbase_di): Likewise.


RE: [PATCH, testsuite] MIPS: Skip msa-builtins-err.c if there is no assembly output.

2016-12-09 Thread Matthew Fortune
Toma Tabacu  writes:
> The msa-builtins-err.c test is failing in the following configuration:
> -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects
> This is because the errors it is checking for are triggered by assembly
> generation, which is prevented by -fno-fat-lto-objects.
> 
> This patch fixes this by adding a dg-skip-if for -fno-fat-lto-objects.
> 
> Tested with mips-mti-elf.
> 
> Regards,
> Toma Tabacu
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.target/mips/msa-builtins-err.c (dg-skip-if): Do not run the test
>   if -fno-fat-lto-objects is present.

You don't need the (dg-skip-if) here, no specific reason but people
don't tend to do it.

It's a shame this is the only way to deal with this but I see aarch64 have
to resort to the same thing for error checking tests.

Thanks for the fix, OK to commit.

Matthew


Re: [PATCH] warn on overflow in calls to allocation functions (bugs 77531 and 78284)

2016-12-09 Thread Christophe Lyon
On 9 December 2016 at 00:54, Martin Sebor  wrote:
>>> +enabled with @option{-Wextra}.
>>
>> So I think we should in the immediate term not enable this in Wextra.
>> However, I think for gcc-8 we should revisit after fixing GCC to be
>> cleaner WRT alloc-zero.
>>
>> So disable alloc-zero by default, comment typo and potentially adding
>> the GTY marker to alloc_object_size_limit and this is OK.
>
>
> Thanks.  Committed in r243470 with the changes above.
>
> Martin

Hi,

The new test attr-alloc_size-3.c fails on arm* targets:
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:
In function 'test_schar_cst':
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:175:3:
warning: argument 1 value '-128' is negative
[-Walloc-size-larger-than=]
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:42:7:
note: in a call to allocation function 'f_schar_1' declared here
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:176:3:
warning: argument 1 value '-1' is negative [-Walloc-size-larger-than=]
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:42:7:
note: in a call to allocation function 'f_schar_1' declared here
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:181:3:
warning: argument 2 value '-128' is negative
[-Walloc-size-larger-than=]
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:43:7:
note: in a call to allocation function 'f_schar_2' declared here
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:182:3:
warning: argument 1 value '-128' is negative
[-Walloc-size-larger-than=]
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:183:3:
warning: argument 2 value '-1' is negative [-Walloc-size-larger-than=]
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:43:7:
note: in a call to allocation function 'f_schar_2' declared here
/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/testsuite/gcc.dg/attr-alloc_size-3.c:184:3:
warning: argument 1 value '-1' is negative [-Walloc-size-larger-than=]

[]

Christophe


Re: [PATCH] Escape non-printable chars in dumped strings.

2016-12-09 Thread Richard Biener
On Thu, Dec 8, 2016 at 4:00 PM, Martin Liška  wrote:
> There's a patch that adds a new test-case for that.

Ok.

> Martin


Re: [PATCH] Escape non-printable chars in dumped strings.

2016-12-09 Thread Richard Biener
On Thu, Dec 8, 2016 at 2:37 PM, Martin Liška  wrote:
> Hello.
>
> Following patch changes behavior in pretty_print_string, where all 
> non-printable
> characters are encoded as \x%x. Currently, when some non-printable characters 
> are directly
> printed to a dump file stream. That makes it complicated to read a dump file 
> for instance
> via a Python script.
>
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>
> Ready to be installed?

Ok.  Does ISPRINT ('\') yield true or false?  That is, I suppose we
want to escape that?

> Martin


[PATCH] Enhance analyze_brprob script

2016-12-09 Thread Martin Liška
Following patch enhances scripts and fixed various small issues.

Ready to be installed?

Martin
>From 626b70eb3526d848e2f1741f8b2384c518d2067b Mon Sep 17 00:00:00 2001
From: marxin 
Date: Fri, 9 Dec 2016 11:00:16 +0100
Subject: [PATCH] Enhance analyze_brprob script

contrib/ChangeLog:

2016-12-09  Martin Liska  

	* analyze_brprob.py: Add new column to output and new sorting
	option. Fix coding style to not exceed 80 characters.
	* analyze_brprob_spec.py: Add new sorting
	option. Fix coding style to not exceed 80 characters.
---
 contrib/analyze_brprob.py  | 39 ---
 contrib/analyze_brprob_spec.py |  9 ++---
 2 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py
index 7e66271..b4dbbc4 100755
--- a/contrib/analyze_brprob.py
+++ b/contrib/analyze_brprob.py
@@ -69,7 +69,8 @@ import argparse
 
 from math import *
 
-counter_aggregates = set(['combined', 'first match', 'DS theory', 'no prediction'])
+counter_aggregates = set(['combined', 'first match', 'DS theory',
+'no prediction'])
 
 def percentage(a, b):
 return 100.0 * a / b
@@ -93,12 +94,16 @@ class Summary:
 def __init__(self, name):
 self.name = name
 self.branches = 0
+self.successfull_branches = 0
 self.count = 0
 self.hits = 0
 self.fits = 0
 
 def get_hitrate(self):
-return self.hits / self.count
+return 100.0 * self.hits / self.count
+
+def get_branch_hitrate(self):
+return 100.0 * self.successfull_branches / self.branches
 
 def count_formatted(self):
 v = self.count
@@ -109,10 +114,11 @@ class Summary:
 return "%.1f%s" % (v, 'Y')
 
 def print(self, branches_max, count_max):
-print('%-40s %8i %5.1f%% %6.2f%% / %6.2f%% %14i %8s %5.1f%%' %
+print('%-40s %8i %5.1f%% %11.2f%% %7.2f%% / %6.2f%% %14i %8s %5.1f%%' %
 (self.name, self.branches,
 percentage(self.branches, branches_max),
-percentage(self.hits, self.count),
+self.get_branch_hitrate(),
+self.get_hitrate(),
 percentage(self.fits, self.count),
 self.count, self.count_formatted(),
 percentage(self.count, count_max)))
@@ -129,11 +135,16 @@ class Profile:
 
 s = self.heuristics[name]
 s.branches += 1
+
 s.count += count
 if prediction < 50:
 hits = count - hits
+remaining = count - hits
+if hits >= remaining:
+s.successfull_branches += 1
+
 s.hits += hits
-s.fits += max(hits, count - hits)
+s.fits += max(hits, remaining)
 
 def add_loop_niter(self, niter):
 if niter > 0:
@@ -150,15 +161,18 @@ class Profile:
 branches_max = self.branches_max()
 
 sorter = lambda x: x.branches
-if sorting == 'hitrate':
+if sorting == 'branch-hitrate':
+sorter = lambda x: x.get_branch_hitrate()
+elif sorting == 'hitrate':
 sorter = lambda x: x.get_hitrate()
 elif sorting == 'coverage':
 sorter = lambda x: x.count
 elif sorting == 'name':
 sorter = lambda x: x.name.lower()
 
-print('%-40s %8s %6s  %-16s %14s %8s %6s' % (group_name,
-'BRANCHES', '(REL)', 'HITRATE', 'COVERAGE', 'COVERAGE', '(REL)'))
+print('%-40s %8s %6s %12s %18s %14s %8s %6s' %
+('HEURISTICS', 'BRANCHES', '(REL)',
+'BR. HITRATE', 'HITRATE', 'COVERAGE', 'COVERAGE', '(REL)'))
 for h in sorted(heuristics, key = sorter):
 h.print(branches_max, count_max)
 
@@ -183,12 +197,15 @@ class Profile:
 print('  median # of iter: %.2f' % median(self.niter_vector))
 for v in [1, 5, 10, 20, 30]:
 cut = 0.01 * v
-print('  avg. (%d%% cutoff) # of iter: %.2f' % (v, average_cutoff(self.niter_vector, cut)))
+print('  avg. (%d%% cutoff) # of iter: %.2f'
+% (v, average_cutoff(self.niter_vector, cut)))
 
 parser = argparse.ArgumentParser()
-parser.add_argument('dump_file', metavar = 'dump_file', help = 'IPA profile dump file')
+parser.add_argument('dump_file', metavar = 'dump_file',
+help = 'IPA profile dump file')
 parser.add_argument('-s', '--sorting', dest = 'sorting',
-choices = ['branches', 'hitrate', 'coverage', 'name'], default = 'branches')
+choices = ['branches', 'branch-hitrate', 'hitrate', 'coverage', 'name'],
+default = 'branches')
 
 args = parser.parse_args()
 
diff --git a/contrib/analyze_brprob_spec.py b/contrib/analyze_brprob_spec.py
index effdc21..908db39 100755
--- a/contrib/analyze_brprob_spec.py
+++ b/contrib/analyze_brprob_spec.py
@@ -25,9 +25,11 @@ import argparse
 script_location = os.path.realpath(__file__)
 
 parser = argparse.ArgumentParser()
-parser.add_argument('location', metavar = 'dump_file', help = '

Re: [PATCH] Fix 78550 ICE with bit-field initialization

2016-12-09 Thread Richard Biener
On Thu, Dec 8, 2016 at 5:38 PM, Nathan Sidwell  wrote:
> This patch fixes 78550, where we ICE in varasm as we discover a
> code-generating NOP_EXPR of an INTEGER_CST.  output_constructor (varasm.c)
> has a STRIP_NOPs, but that leaves the NOP alone, as it is truncating a
> regular QI mode operand to a 1 bit type.
>
> That tree is generated in convert.c:
>   /* If TYPE is an enumeral type or a type with a precision less
>  than the number of bits in its mode, do the conversion to the
>  type corresponding to its mode, then do a nop conversion
>  to TYPE.  */
> 
>   return fold_build1_loc (dofold, loc, NOP_EXPR, type, ...);
> }
> Fixed by changing it to maybe_fold_build1_loc.  Surrounding code uses that
> function.
>
> ok?

Ok.

Thanks,
Richard.

> nathan
> --
> Nathan Sidwell


Re: [PATCH] Escape non-printable chars in dumped strings.

2016-12-09 Thread Martin Liška
On 12/09/2016 11:00 AM, Richard Biener wrote:
> On Thu, Dec 8, 2016 at 2:37 PM, Martin Liška  wrote:
>> Hello.
>>
>> Following patch changes behavior in pretty_print_string, where all 
>> non-printable
>> characters are encoded as \x%x. Currently, when some non-printable 
>> characters are directly
>> printed to a dump file stream. That makes it complicated to read a dump file 
>> for instance
>> via a Python script.
>>
>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>>
>> Ready to be installed?
> 
> Ok.  Does ISPRINT ('\') yield true or false?  That is, I suppose we
> want to escape that?

You mean '\\', which is already covered by a case:

case '\\':
  pp_string (pp, "");
  break;

I'm going to install the patch.

Martin


> 
>> Martin



Re: libgo patch committed: Copy hash code from Go 1.7 runtime

2016-12-09 Thread Sebastian Huber

On 08/12/16 17:37, Ian Lance Taylor wrote:

+// For gccgo, use go:linkname to rename compiler-called functions to
+// themselves, so that the compiler will export them.
+//
+//go:linkname memhash runtime.memhash
+
+const (
+   // Constants for multiplication: four random odd 64-bit numbers.
+   m1 = 16877499708836156737
+   m2 = 2820277070424839065
+   m3 = 9497967016996688599
+   m4 = 15839092249703872147
+)


Out of curiosity, how did you generate these numbers?

--
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail  : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



Re: [PATCH, middle-end]: Fix PR78738, unrecognized insn with -ffast-math

2016-12-09 Thread Richard Biener
On Thu, Dec 8, 2016 at 10:44 PM, Uros Bizjak  wrote:
> Hello!
>
> Attached patch fixes fall-out from excess-precision improvements
> patch. As shown in the PR, the code throughout the compiler assumes
> FLAG_PRECISION_FAST when flag_unsafe_math_optimizations flag is in
> effect. The patch puts back two lines, removed by excess-precision
> improvements patch.
>
> 2016-12-08  Uros Bizjak  
>
> PR middle-end/78738
> * toplev.c (init_excess_precision): Initialize flag_excess_precision
> to EXCESS_PRECISION_FAST for flag_unsafe_math_optimizations.
>
> testsuite/ChangeLog:
>
> 2016-12-08  Uros Bizjak  
>
> PR middle-end/78738
> * gcc.target/i386/pr78738.c: New test.
>
> Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
>
> OK for mainline?

Hmm, I think it belongs to set_unsafe_math_optimization_flags instead
(and be consistent if -fexcess-precision was manually specified).

Also where do we assume connection between -funsafe-math-optimizations
and FLAG_PRECISION_FAST?  We have two flags so we should fix any
user that looks at one but means the other.

Richard.

>
> Uros.


Re: [PATCH] Fix PR78721

2016-12-09 Thread Richard Biener
On Fri, Dec 9, 2016 at 5:25 AM, kugan  wrote:
> Hi,
>
> in propagate_vr_accross_jump_function, drop_tree_overflow should be after
> fold_convert. Attached patch changes this.
>
> Bootstrapped and regression tested on x86_64-linux-gnu with no new
> regressions. Is this OK for trunk?

Ok.

Richard.

> Thanks,
> Kugan
>
> gcc/testsuite/ChangeLog:
>
> 2016-12-09  Kugan Vivekanandarajah  
>
> PR ipa/78721
> * gcc.dg/pr78721.c: New test.
>
>
> gcc/ChangeLog:
>
> 2016-12-09  Kugan Vivekanandarajah  
>
> PR ipa/78721
> * ipa-cp.c (propagate_vr_accross_jump_function): drop_tree_overflow
> after fold_convert.
>
>
>
>
>
>
>
>
>
>


Re: [PATCH] Escape non-printable chars in dumped strings.

2016-12-09 Thread Richard Biener
On Fri, Dec 9, 2016 at 11:05 AM, Martin Liška  wrote:
> On 12/09/2016 11:00 AM, Richard Biener wrote:
>> On Thu, Dec 8, 2016 at 2:37 PM, Martin Liška  wrote:
>>> Hello.
>>>
>>> Following patch changes behavior in pretty_print_string, where all 
>>> non-printable
>>> characters are encoded as \x%x. Currently, when some non-printable 
>>> characters are directly
>>> printed to a dump file stream. That makes it complicated to read a dump 
>>> file for instance
>>> via a Python script.
>>>
>>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>>>
>>> Ready to be installed?
>>
>> Ok.  Does ISPRINT ('\') yield true or false?  That is, I suppose we
>> want to escape that?
>
> You mean '\\', which is already covered by a case:
>
> case '\\':
>   pp_string (pp, "");
>   break;

Ah, I see.

> I'm going to install the patch.

Thanks.

> Martin
>
>
>>
>>> Martin
>


Re: [RFC PATCH] avoid printing type suffix with %E (PR c/78165)

2016-12-09 Thread Rainer Orth
Jeff Law  writes:

> On 11/19/2016 02:04 PM, Martin Sebor wrote:
>> On 10/26/2016 02:46 PM, Joseph Myers wrote:
>>> On Wed, 26 Oct 2016, Martin Sebor wrote:
>>>
 The attached patch implements one such approach by having the pretty
 printer recognize the space format flag to suppress the type suffix,
 so "%E" still prints the suffix but "% E" does not.  I did this to
 preserve the existing output but I think it would be nicer to avoid
 printing the suffix with %E and treat (for instance) the pound sign
 as a request to add the suffix.  I have tested the attached patch
 but not the alternative.
>>>
>>> I think printing the suffixes is a relic of %E being used to print full
>>> expressions.
>>>
>>> It's established by now that printing expressions reconstructed from
>>> trees
>>> is a bad idea; we can get better results by having precise location
>>> ranges
>>> and underlining the relevant part of the source.  So if we could make
>>> sure
>>> nowhere is trying the use %E (or %qE, etc.) with expressions that might
>>> not be constants, where the type might be relevant, then we'd have
>>> confidence that stopping printing the suffix is safe.  But given the low
>>> quality of the reconstructed expressions, it's probably safe anyway.
>>>
>>> (Most %qE uses are for identifiers not expressions.  If we give
>>> identifiers a different static type from "tree" - and certainly there
>>> isn't much reason for them to have the same type as expressions - then
>>> we'll need to change the format for either identifiers or expressions.)
>>
>> Attached is a trivial patch to remove the suffix.  I didn't see
>> any failures in the test suite as a result.  I didn't attempt to
>> remove the type suffix from any tests (nor did my relatively
>> superficial search find any) but it will help simplify the tests
>> for my patches that are still in the review queue.
>>
>> I should add to the rationale for the change I gave in my reply
>> to Jeff:
>>
>>   https://gcc.gnu.org/ml/gcc-patches/2016-11/msg01692.html
>>
>> that the print_dec[su] function that's sometimes used to format
>> integers in warning messages (e.g., by the -Walloca-larger-than
>> pass) doesn't add the suffix because it doesn't have knowledge
>> of the argument's type (it operates on wide_int).  That further
>> adds to the inconsistency in diagnostics.  This patch makes all
>> integers in diagnostics consistent regardless of their type.
>>
>> Thanks
>> Martin
>>
>> gcc-78165.diff
>>
>>
>> PR c/78165 - avoid printing type suffix for constants in %E output
>>
>> gcc/c-family/ChangeLog:
>>
>>  PR c/78165
>>  * c-pretty-print (pp_c_integer_constant): Avoid formatting type
>>  suffix.
> I think you and Joseph have made a practical case for dropping the type
> suffix.
>
> Ok for the trunk.

The check-in lacked the gcc/testsuite ChangeLog.  Besides, the patch
caused a testsuite regression on Solaris with /bin/as (sparc and x86, 32
and 64-bit):

+FAIL: g++.dg/debug/dwarf2/typedef1.C  -std=gnu++11  scan-assembler-times 
DW_AT_name: "foo<1>"|"foo<1u>.."[^\\n]*DW_AT_name 1
+FAIL: g++.dg/debug/dwarf2/typedef1.C  -std=gnu++14  scan-assembler-times 
DW_AT_name: "foo<1>"|"foo<1u>.."[^\\n]*DW_AT_name 1
+FAIL: g++.dg/debug/dwarf2/typedef1.C  -std=gnu++98  scan-assembler-times 
DW_AT_name: "foo<1>"|"foo<1u>.."[^\\n]*DW_AT_name 1

Turns out an incomplete adjustment to the pattern, fixed as follows.
Will commit as obvious once testing on more configurations (gas, Linux)
has completed.

Rainer

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


2016-12-09  Rainer Orth  

* g++.dg/debug/dwarf2/typedef1.C: Adjust pattern for last change.

# HG changeset patch
# Parent  9cf8fdbb2f5fbebf7cf273c95a1d1e72567aa76c
Fix g++.dg/debug/dwarf2/typedef1.C

diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C b/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C
--- a/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/typedef1.C
@@ -3,7 +3,7 @@
 // { dg-options "-gdwarf-2 -dA -fno-debug-types-section" }
 // { dg-do compile }
 // { dg-final { scan-assembler-times "DW_TAG_structure_type" 2 } }
-// { dg-final { scan-assembler-times "DW_AT_name: \"foo<1>\"|\"foo<1u>..\"\[^\n\]*DW_AT_name" 1 } }
+// { dg-final { scan-assembler-times "DW_AT_name: \"foo<1>\"|\"foo<1>..\"\[^\n\]*DW_AT_name" 1 } }
 // { dg-final { scan-assembler-times "DW_TAG_enumeration_type" 2 } }
 // { dg-final { scan-assembler-times "DW_AT_name: \"typedef foo<1>::type type\"|\"typedef foo<1>::type type..\"\[^\n\]*DW_AT_name" 1 } }
 // { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_enumeration_type" 1 } }


Re: [PATCH] Fill bitregion_{start,end} in store_constructor (PR, tree-optimization/78428).

2016-12-09 Thread Martin Liška
On 11/23/2016 11:49 AM, Richard Biener wrote:
> On Wed, Nov 23, 2016 at 11:26 AM, Martin Liška  wrote:
>> Following patch fixes situation where we do a store to a bitfield which
>> is at boundary of a record. This leads to usage of wider store, leading
>> to overwriting a following memory location.
>>
>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>> Apart from that, the reported test-case in PR works on x86_64-linux-gnu.
>>
>> Ready to be installed?
> 
> +  HOST_WIDE_INT bitregion_end
> += exp_size == -1 ? 0 : exp_size * BITS_PER_UNIT - 1;
> 
> I don't think looking at the CONSTRUCTOR to determine bitregion_end is
> a good idea.
> The function gets 'size' as argument which is documented as "number of
> bytes we are
> allowed to modify" - so better use that.
> 
> @@ -6308,7 +6314,8 @@ store_constructor (tree exp, rtx target, int
> cleared, HOST_WIDE_INT size,
> MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
>   }
> 
> -   store_constructor_field (to_rtx, bitsize, bitpos, mode,
> +   store_constructor_field (to_rtx, bitsize, bitpos,
> +0, bitregion_end, mode,
>  value, cleared,
>  get_alias_set (TREE_TYPE (field)),
>  reverse);
> 
> this stores to to_rtx which may be offsetted from target this means in this 
> case
> bitregion_end is not conservative enough - you'd need to resort to the
> field width
> in that case I guess (and for variable field size not specify any end
> -- I suppose
> the 'size' store_constructor gets might also be "unknown"?).  But maybe all
> the non-constant offset / size cases are "dead code" now that we are in 
> GIMPLE?
> Note they likely can only appear from Ada code anyway -- CCing Eric.
> 
> I suppose a "safe" thing to do would be to give up on the first
> variable offset/size
> and re-set bitregion_end to zero for this and all following fields.

Ok. I'm sending a patch that put gcc_unreachable to places where either size
or (and) offset is a non-constant. This survives regression tests (including 
ada)
on x86_64-linux-gnu. Apart from that normal bootstrap + regression tests works 
fine
on ppc64le-redhat-linux.

I'm not sure whether there can be a code that has variable size and offset?

Martin

> 
> The other cases look fine to me.
> 
> Thanks,
> Richard.
> 
>> Martin

>From c8d3e7c33c22bfdaf9e285e9e747701b8646cdf2 Mon Sep 17 00:00:00 2001
From: marxin 
Date: Tue, 22 Nov 2016 10:15:42 +0100
Subject: [PATCH] Fill bitregion_{start,end} in store_constructor (PR
 tree-optimization/78428).

gcc/ChangeLog:

2016-12-08  Martin Liska  

	* expr.c (store_constructor_field): Add new arguments to the
	function.
	(store_constructor): Set up bitregion_end and add
	gcc_unreachable to fields that have either non-constant size
	or (and) offset.

gcc/testsuite/ChangeLog:

2016-12-08  Martin Liska  

	* gcc.dg/tree-ssa/pr78428.c: New test.
---
 gcc/expr.c  | 52 +
 gcc/testsuite/gcc.dg/tree-ssa/pr78428.c | 27 +
 2 files changed, 47 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr78428.c

diff --git a/gcc/expr.c b/gcc/expr.c
index fe752fb..88da8dd 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -80,7 +80,8 @@ static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
 static rtx_insn *compress_float_constant (rtx, rtx);
 static rtx get_subtarget (rtx);
 static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
- HOST_WIDE_INT, machine_mode,
+ HOST_WIDE_INT, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, machine_mode,
  tree, int, alias_set_type, bool);
 static void store_constructor (tree, rtx, int, HOST_WIDE_INT, bool);
 static rtx store_field (rtx, HOST_WIDE_INT, HOST_WIDE_INT,
@@ -6077,7 +6078,10 @@ all_zeros_p (const_tree exp)
 
 static void
 store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
-			 HOST_WIDE_INT bitpos, machine_mode mode,
+			 HOST_WIDE_INT bitpos,
+			 unsigned HOST_WIDE_INT bitregion_start,
+			 unsigned HOST_WIDE_INT bitregion_end,
+			 machine_mode mode,
 			 tree exp, int cleared,
 			 alias_set_type alias_set, bool reverse)
 {
@@ -6112,8 +6116,8 @@ store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
 			 reverse);
 }
   else
-store_field (target, bitsize, bitpos, 0, 0, mode, exp, alias_set, false,
-		 reverse);
+store_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode,
+		 exp, alias_set, false, reverse);
 }
 
 
@@ -6148,6 +6152,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size,
 {
   tree type = TREE_TYPE (exp);
   HOST_WIDE_INT exp_size = int_size_in_bytes (type);
+  HOST_WIDE_INT bitregion_end = size > 0 ? size * BITS_PER_UNIT - 1 : 0;
 
   switch (TREE_CODE (type))
 {
@@ -6225,7 +6230,7 @@ store_construct

[PATCH TEST]Add test for PR78652

2016-12-09 Thread Bin Cheng
Hi,
PR78652 was fixed by patch for PR77856, this patch adds a test for it.  Test 
result checked, is it OK?

Thanks,
bin

gcc/testsuite/ChangeLog
2016-12-07  Bin Cheng  

PR rtl-optimization/78652
* gcc.c-torture/execute/pr78652.c: New test.diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78652.c 
b/gcc/testsuite/gcc.c-torture/execute/pr78652.c
new file mode 100644
index 000..277f108
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr78652.c
@@ -0,0 +1,77 @@
+/* PR rtl-optimization/78652 */
+/* { dg-options "-fno-strict-aliasing" } */
+
+short a, b = 1, p, t;
+struct {
+  signed f1 : 9;
+} m = {3};
+
+int c, g = 0, h = 8, i, k, l, q, r, s, w, x = 9;
+long long d = 1;
+long long e = 1;
+char f[9][6][4] = {{{1}}};
+short j[6] = {1};
+
+unsigned n;
+static long long *o = &e;
+char u;
+short *v;
+char *y = &f[6][4][3];
+short fn1 (short p1) { return a == 0 ? p1 : p1 % a; }
+
+static int *fn2 (signed char p1, int p2, signed char p3) {
+lbl_2057:
+  if (n >= (q >= fn1 (3)))
+return &r;
+  if (p2)
+t = u;
+  *v = (t | *o) * p2;
+  for (;;) {
+for (; u <= 1;)
+  goto lbl_2057;
+if (p1)
+  s = g = 0;
+  }
+}
+
+void fn3 (int *p1) {
+  if (*p1)
+;
+  else {
+x = w;
+for (;;)
+  ;
+  }
+}
+
+int *fn4 (long p1) {
+  for (; p1; p1--)
+e = 1;
+  y = 0;
+  return &h;
+}
+
+__attribute__((noinline))
+void bar (int a)
+{
+  if (a != 3)
+__builtin_abort ();
+}
+
+__attribute__((section(".text")))
+int main () {
+  int *z;
+  long t1;
+  long long *t2 = &d;
+  *t2 = b;
+  z = fn4 (*t2);
+  fn3 (z);
+  short *t3 = &j[0];
+  *t3 = f[6][4][3] >= (b = i);
+  t1 = p < n;
+  fn2 (c < t1 >= m.f1, l, k);
+  j[5]++;
+  bar (m.f1);
+
+  return 0;
+}


RE: [PATCH, testsuite] MIPS: Upgrade to R2 for -mnan=2008 and -mabs=2008.

2016-12-09 Thread Matthew Fortune
Toma Tabacu 
> The -mnan=2008 and -mabs=2008 options are not supported on pre-R2 targets.
> This results in failures for tests which use these options, such as 
> nan-2008.c,
> fabs-2008.c etc.
> 
> This patch makes the testsuite upgrade to R2 if -mnan=2008 and -mabs=2008 are
> used as test options.
> 
> Tested with mips-mti-elf.
> 
> Regards,
> Toma Tabacu
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.target/mips/mips.exp (mips-dg-options): Upgrade to R2 for
>   -mnan=2008 and -mabs=2008.

OK, thanks.

Matthew


[PATCH] rs6000: clz/ctz/ffs improvement (PR78683)

2016-12-09 Thread Segher Boessenkool
On CPUs that implement popcnt[wd] but not cnttz[wd] we can do better for
the ctz sequences than we do today.

CL[TZ]_DEFINED_VALUE_AT_ZERO can return 2, since we always return the
same fixed value (only dependent on TARGET_* options).

I originally tried to have the generic code handle this; that would be
too much surgery for stage 3 though.

Bootstrapped and tested on powerpc64-linux {-m32,-m64}; also tested
manually with {-m32,-m64} -mcpu=power{4,7,9}.  Is this okay for trunk?


Segher


2016-12-09  Segher Boessenkool  

PR target/78683
* config/rs6000/rs6000.h (CLZ_DEFINED_VALUE_AT_ZERO):
Use GET_MODE_BITSIZE.  Return 2.
(CTZ_DEFINED_VALUE_AT_ZERO): Use GET_MODE_BITSIZE.  Return 2. Handle
TARGET_POPCNTD the same as TARGET_CTZ.
* config/rs6000/rs6000.md (ctz2): Reimplement.
(ffs2): Reimplement.

---
 gcc/config/rs6000/rs6000.h  | 11 
 gcc/config/rs6000/rs6000.md | 62 +++--
 2 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 5d56927..fe314bf 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2199,14 +2199,15 @@ do {
 \
 
 /* The cntlzw and cntlzd instructions return 32 and 64 for input of zero.  */
 #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
-  ((VALUE) = ((MODE) == SImode ? 32 : 64), 1)
+  ((VALUE) = GET_MODE_BITSIZE (MODE), 2)
 
 /* The CTZ patterns that are implemented in terms of CLZ return -1 for input of
-   zero.  The hardware instructions added in Power9 return 32 or 64.  */
+   zero.  The hardware instructions added in Power9 and the sequences using
+   popcount return 32 or 64.  */
 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
-  ((!TARGET_CTZ)   \
-   ? ((VALUE) = -1, 1) \
-   : ((VALUE) = ((MODE) == SImode ? 32 : 64), 1))
+  (TARGET_CTZ || TARGET_POPCNTD
\
+   ? ((VALUE) = GET_MODE_BITSIZE (MODE), 2)\
+   : ((VALUE) = -1, 2))
 
 /* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4726d73..777b996 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -2220,17 +2220,8 @@ (define_insn "clz2"
   [(set_attr "type" "cntlz")])
 
 (define_expand "ctz2"
-  [(set (match_dup 2)
-   (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
-   (set (match_dup 3)
-   (and:GPR (match_dup 1)
-(match_dup 2)))
-   (set (match_dup 4)
-   (clz:GPR (match_dup 3)))
-   (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-  (minus:GPR (match_dup 5)
- (match_dup 4)))
- (clobber (reg:GPR CA_REGNO))])]
+   [(set (match_operand:GPR 0 "gpc_reg_operand")
+(ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
   ""
 {
   if (TARGET_CTZ)
@@ -2239,10 +2230,26 @@ (define_expand "ctz2"
   DONE;
 }
 
-  operands[2] = gen_reg_rtx (mode);
-  operands[3] = gen_reg_rtx (mode);
-  operands[4] = gen_reg_rtx (mode);
-  operands[5] = GEN_INT (GET_MODE_BITSIZE (mode) - 1);
+  rtx tmp1 = gen_reg_rtx (mode);
+  rtx tmp2 = gen_reg_rtx (mode);
+  rtx tmp3 = gen_reg_rtx (mode);
+
+  if (TARGET_POPCNTD)
+{
+  emit_insn (gen_add3 (tmp1, operands[1], constm1_rtx));
+  emit_insn (gen_one_cmpl2 (tmp2, operands[1]));
+  emit_insn (gen_and3 (tmp3, tmp1, tmp2));
+  emit_insn (gen_popcntd2 (operands[0], tmp3));
+}
+  else
+{
+  emit_insn (gen_neg2 (tmp1, operands[1]));
+  emit_insn (gen_and3 (tmp2, operands[1], tmp1));
+  emit_insn (gen_clz2 (tmp3, tmp2));
+  emit_insn (gen_sub3 (operands[0], GEN_INT ( - 1), tmp3));
+}
+
+  DONE;
 })
 
 (define_insn "ctz2_hw"
@@ -2253,23 +2260,18 @@ (define_insn "ctz2_hw"
   [(set_attr "type" "cntlz")])
 
 (define_expand "ffs2"
-  [(set (match_dup 2)
-   (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))
-   (set (match_dup 3)
-   (and:GPR (match_dup 1)
-(match_dup 2)))
-   (set (match_dup 4)
-   (clz:GPR (match_dup 3)))
-   (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "")
-  (minus:GPR (match_dup 5)
- (match_dup 4)))
- (clobber (reg:GPR CA_REGNO))])]
+  [(set (match_operand:GPR 0 "gpc_reg_operand")
+   (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
   ""
 {
-  operands[2] = gen_reg_rtx (mode);
-  operands[3] = gen_reg_rtx (mode);
-  operands[4] = gen_reg_rtx (mode);
-  operands[5] = GEN_INT (GET_MODE_BITSIZE (mode));
+  rtx tmp1 = gen_reg_rtx (mode);
+  rtx tmp2 = gen_reg_rtx (mode);
+  rtx tmp3 = gen_reg_rtx (mode);
+  e

Re: [PATCH] Enhance analyze_brprob script

2016-12-09 Thread Martin Liška
On 12/09/2016 11:02 AM, Martin Liška wrote:
> Following patch enhances scripts and fixed various small issues.
> 
> Ready to be installed?
> 
> Martin
> 

I forgot to squash commits, this is the right patch.

M.
>From c64469dcdf114ab3a432a9006be3d291df62b8a1 Mon Sep 17 00:00:00 2001
From: marxin 
Date: Thu, 8 Dec 2016 18:01:15 +0100
Subject: [PATCH] Enhance analyze_brprob script

contrib/ChangeLog:

2016-12-09  Martin Liska  

	* analyze_brprob.py: Add new column to output and new sorting
	option. Fix coding style to not exceed 80 characters.
	* analyze_brprob_spec.py: Add new sorting
	option. Fix coding style to not exceed 80 characters.
---
 contrib/analyze_brprob.py  | 80 +-
 contrib/analyze_brprob_spec.py | 10 --
 2 files changed, 70 insertions(+), 20 deletions(-)

diff --git a/contrib/analyze_brprob.py b/contrib/analyze_brprob.py
index c083d2b..b4dbbc4 100755
--- a/contrib/analyze_brprob.py
+++ b/contrib/analyze_brprob.py
@@ -69,6 +69,9 @@ import argparse
 
 from math import *
 
+counter_aggregates = set(['combined', 'first match', 'DS theory',
+'no prediction'])
+
 def percentage(a, b):
 return 100.0 * a / b
 
@@ -91,12 +94,16 @@ class Summary:
 def __init__(self, name):
 self.name = name
 self.branches = 0
+self.successfull_branches = 0
 self.count = 0
 self.hits = 0
 self.fits = 0
 
 def get_hitrate(self):
-return self.hits / self.count
+return 100.0 * self.hits / self.count
+
+def get_branch_hitrate(self):
+return 100.0 * self.successfull_branches / self.branches
 
 def count_formatted(self):
 v = self.count
@@ -106,6 +113,16 @@ class Summary:
 v /= 1000.0
 return "%.1f%s" % (v, 'Y')
 
+def print(self, branches_max, count_max):
+print('%-40s %8i %5.1f%% %11.2f%% %7.2f%% / %6.2f%% %14i %8s %5.1f%%' %
+(self.name, self.branches,
+percentage(self.branches, branches_max),
+self.get_branch_hitrate(),
+self.get_hitrate(),
+percentage(self.fits, self.count),
+self.count, self.count_formatted(),
+percentage(self.count, count_max)))
+
 class Profile:
 def __init__(self, filename):
 self.filename = filename
@@ -118,11 +135,16 @@ class Profile:
 
 s = self.heuristics[name]
 s.branches += 1
+
 s.count += count
 if prediction < 50:
 hits = count - hits
+remaining = count - hits
+if hits >= remaining:
+s.successfull_branches += 1
+
 s.hits += hits
-s.fits += max(hits, count - hits)
+s.fits += max(hits, remaining)
 
 def add_loop_niter(self, niter):
 if niter > 0:
@@ -134,20 +156,40 @@ class Profile:
 def count_max(self):
 return max([v.count for k, v in self.heuristics.items()])
 
-def dump(self, sorting):
-sorter = lambda x: x[1].branches
-if sorting == 'hitrate':
-sorter = lambda x: x[1].get_hitrate()
+def print_group(self, sorting, group_name, heuristics):
+count_max = self.count_max()
+branches_max = self.branches_max()
+
+sorter = lambda x: x.branches
+if sorting == 'branch-hitrate':
+sorter = lambda x: x.get_branch_hitrate()
+elif sorting == 'hitrate':
+sorter = lambda x: x.get_hitrate()
 elif sorting == 'coverage':
-sorter = lambda x: x[1].count
+sorter = lambda x: x.count
+elif sorting == 'name':
+sorter = lambda x: x.name.lower()
+
+print('%-40s %8s %6s %12s %18s %14s %8s %6s' %
+('HEURISTICS', 'BRANCHES', '(REL)',
+'BR. HITRATE', 'HITRATE', 'COVERAGE', 'COVERAGE', '(REL)'))
+for h in sorted(heuristics, key = sorter):
+h.print(branches_max, count_max)
+
+def dump(self, sorting):
+heuristics = self.heuristics.values()
+if len(heuristics) == 0:
+print('No heuristics available')
+return
+
+special = list(filter(lambda x: x.name in counter_aggregates,
+heuristics))
+normal = list(filter(lambda x: x.name not in counter_aggregates,
+heuristics))
 
-print('%-40s %8s %6s  %-16s %14s %8s %6s' % ('HEURISTICS', 'BRANCHES', '(REL)',
-  'HITRATE', 'COVERAGE', 'COVERAGE', '(REL)'))
-for (k, v) in sorted(self.heuristics.items(), key = sorter):
-print('%-40s %8i %5.1f%% %6.2f%% / %6.2f%% %14i %8s %5.1f%%' %
-(k, v.branches, percentage(v.branches, self.branches_max ()),
- percentage(v.hits, v.count), percentage(v.fits, v.count),
- v.count, v.count_formatted(), percentage(v.count, self.count_max()) ))
+self.print_group(sorting, 'HEURISTICS', normal)
+print()
+self.print_group(sorting, 'HEURISTIC AGGREGATES', special)
 

Re: [PR78365] ICE in determine_value_range, at tree-ssa-loo p-niter.c:413

2016-12-09 Thread Martin Jambor
Hi,

On Fri, Dec 09, 2016 at 03:36:44PM +1100, kugan wrote:
> On 07/12/16 21:08, Martin Jambor wrote:
> > On Mon, Nov 28, 2016 at 04:25:00PM +1100, kugan wrote:
> >
> > ...
> >
> > > Here is a patch that does this. To fox PR78365, in
> > > ipa_get_callee_param_type, I am now checking DECL_ARGUMENTS first. I lto
> > > bootstrapped and regression tested on x86_64-linux-gnu and ppc64le-linux
> > > with no new regressions. I will build Firefox and measure the memory usage
> > > as Honza suggested based on the feedback.
> > > 
> > 
> > So, do you have any numbers?
> I will do it. How do you measure the gcc's memory usage while building
> Firefox. I saw Honza's LTO blog talks about using vmstat result. Any tips
> please?

I asked Martin Liska how he does it and he replied with:

  Steps:

  1) clone git repository: https://github.com/marxin/script-misc

  2) Run command that does an LTO linking

  3) ./system_top.py > /tmp/log
  Run that in a separate terminal, terminate the script after the LTO linking
  finishes.

  4) ./vmstat_parser.py /tmp/log
  Plot the collected data.

so try that :-)   As far as I know, it uses vmstat.  Or maybe Honza
has some other method.


> > ...
> > 
> > > -tree
> > > +static tree
> > >  ipa_get_callee_param_type (struct cgraph_edge *e, int i)
> > >  {
> > >int n;
> > > +  tree t = e->callee ? DECL_ARGUMENTS (e->callee->decl) : NULL_TREE;
> > > +  if (t)
> > > +for (n = 0; n < i; n++)
> > > +  {
> > > + if (!t)
> > > +   return NULL;
> > > + t = TREE_CHAIN (t);
> > > +  }
> > > +  if (t)
> > > +return TREE_TYPE (t);
> > >tree type = (e->callee
> > >  ? TREE_TYPE (e->callee->decl)
> > >  : gimple_call_fntype (e->call_stmt));
> > > -  tree t = TYPE_ARG_TYPES (type);
> > > +  t = TYPE_ARG_TYPES (type);
> > 
> > If TYPE_ARG_TYPES is inherently unreliable then I am afraid you must
> > not fallback on it but rather return NULL if cs->callee is not
> > available and adjust the caller to give up in that case.
> > 
> > (I have checked both testcases that we hope to fix with types in jump
> > functions and the gimple_call_fntype is the same as
> > TREE_TYPE(e->callee->decl) so that does not help either).
>
> Do you like the attached patch where I have removed it.
> 

I am fine with the new patch but you'll need an approval from Honza
or Richi.

I find it a bit saddening that we cannot really rely on
gimple_call_fntype but at least I do not see any other way.

Thanks,

Martin


[PATCH] Fix PR78742

2016-12-09 Thread Richard Biener

The following fixes the bug for the particular testcase by making
cst_and_fits_in_hwi look at the actual value of the constant.

There's still underlying issues in dependence analysis (using ints
to store HOST_WIDE_INTs, failing to check whether the constants
really fit).  But this one makes us behave sanely for sane testcases
and the cst_and_fits_in_hwi should go in independently.

When grepping for cst_and_fits_in_hwi I also spotted one bogus 
use of the predicate.

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

Richard.

2016-12-09  Richard Biener  

PR middle-end/78742
* tree.c (cst_and_fits_in_hwi): Look if the actual value fits.
* tree-object-size.c (compute_builtin_object_size): Use
tree_fits_shwi_p.
* tree-data-ref.c (initialize_matrix_A): Remove excess assert.

* gcc.dg/torture/pr78742.c: New testcase.

Index: gcc/tree.c
===
--- gcc/tree.c  (revision 243474)
+++ gcc/tree.c  (working copy)
@@ -1677,7 +1677,7 @@ bool
 cst_and_fits_in_hwi (const_tree x)
 {
   return (TREE_CODE (x) == INTEGER_CST
- && TYPE_PRECISION (TREE_TYPE (x)) <= HOST_BITS_PER_WIDE_INT);
+ && (tree_fits_shwi_p (x) || tree_fits_uhwi_p (x)));
 }
 
 /* Build a newly constructed VECTOR_CST node of length LEN.  */
Index: gcc/tree-object-size.c
===
--- gcc/tree-object-size.c  (revision 243474)
+++ gcc/tree-object-size.c  (working copy)
@@ -533,7 +533,7 @@ compute_builtin_object_size (tree ptr, i
  tree offset = gimple_assign_rhs2 (def);
  ptr = gimple_assign_rhs1 (def);
 
- if (cst_and_fits_in_hwi (offset)
+ if (tree_fits_shwi_p (offset)
  && compute_builtin_object_size (ptr, object_size_type, psize))
{
  /* Return zero when the offset is out of bounds.  */
Index: gcc/tree-data-ref.c
===
--- gcc/tree-data-ref.c (revision 243474)
+++ gcc/tree-data-ref.c (working copy)
@@ -2118,8 +2114,6 @@ initialize_matrix_A (lambda_matrix A, tr
   switch (TREE_CODE (chrec))
 {
 case POLYNOMIAL_CHREC:
-  gcc_assert (TREE_CODE (CHREC_RIGHT (chrec)) == INTEGER_CST);
-
   A[index][0] = mult * int_cst_value (CHREC_RIGHT (chrec));
   return initialize_matrix_A (A, CHREC_LEFT (chrec), index + 1, mult);
 
Index: gcc/testsuite/gcc.dg/torture/pr78742.c
===
--- gcc/testsuite/gcc.dg/torture/pr78742.c  (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr78742.c  (working copy)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int128 } */
+
+void foo();
+
+void func()
+{
+  int m;
+
+  int tab[m];
+
+  __int128 j;
+  for(; j; j++)
+{
+  tab[j] = 0;
+  tab[j+1] = 0;
+}
+
+  foo();
+}


Re: [PATCH, Fortran, pr78672, ctp1, v1] Gfortran test suite failures with a sanitized compiler

2016-12-09 Thread Andre Vehreschild
Hi Mikael,

thanks a lot for your comments. Note I also have added the reply to your latest
email here.

On Thu, 8 Dec 2016 23:49:57 +0100
Mikael Morin  wrote:



> > diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
> > index 139ce88..4f835b3 100644
> > --- a/gcc/fortran/data.c
> > +++ b/gcc/fortran/data.c
> > @@ -186,7 +186,7 @@ create_character_initializer (gfc_expr *init,
> > gfc_typespec *ts, for (i = 0; i < len; i++)
> > dest[start+i] = rvalue->representation.string[i];
> >  }
> > -  else
> > +  else if (rvalue->value.character.string)  
> This one looks fishy.
> Either rvalue is a character constant and its string should be set, or 
> it’s not a character constant and the value.character.string should not 
> be accessed at all.

You are completely right. This can *only* occur when invalid-code is given to
the compiler. In this case the offending code was:

 data c / = NULL() / 

The syntax may not be correct (just out of my head), but I hope you get the
idea. The sanitizers complaint was that the second argument to the memcpy below
must not be NULL. The above if () makes sure the memcpy does not get called in
this case. So this merely to prevent the compiler from ICEing on systems whose
memcpy is not robust. 

> >  memcpy (&dest[start], rvalue->value.character.string,
> > len * sizeof (gfc_char_t));
> >
> > diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
> > index 8afba84..4e4d17c 100644
> > --- a/gcc/fortran/interface.c
> > +++ b/gcc/fortran/interface.c
> > @@ -2803,6 +2803,7 @@ compare_actual_formal (gfc_actual_arglist **ap,
> > gfc_formal_arglist *formal, int i, n, na;
> >unsigned long actual_size, formal_size;
> >bool full_array = false;
> > +  gfc_ref *actual_arr_ref;
> >
> >actual = *ap;
> >
> > @@ -2942,37 +2943,38 @@ compare_actual_formal (gfc_actual_arglist **ap,
> > gfc_formal_arglist *formal, and assumed-shape dummies, the string length
> > needs to match exactly.  */
> >if (a->expr->ts.type == BT_CHARACTER
> > -  && a->expr->ts.u.cl && a->expr->ts.u.cl->length
> > -  && a->expr->ts.u.cl->length->expr_type == EXPR_CONSTANT
> > -  && f->sym->ts.u.cl && f->sym->ts.u.cl && f->sym->ts.u.cl->length
> > -  && f->sym->ts.u.cl->length->expr_type == EXPR_CONSTANT
> > -  && (f->sym->attr.pointer || f->sym->attr.allocatable
> > -  || (f->sym->as && f->sym->as->type == AS_ASSUMED_SHAPE))
> > -  && (mpz_cmp (a->expr->ts.u.cl->length->value.integer,
> > -   f->sym->ts.u.cl->length->value.integer) != 0))
> > -{
> > -  if (where && (f->sym->attr.pointer || f->sym->attr.allocatable))
> > -gfc_warning (OPT_Wargument_mismatch,
> > - "Character length mismatch (%ld/%ld) between
> > actual "
> > - "argument and pointer or allocatable dummy
> > argument "
> > - "%qs at %L",
> > - mpz_get_si
> > (a->expr->ts.u.cl->length->value.integer),
> > - mpz_get_si
> > (f->sym->ts.u.cl->length->value.integer),
> > - f->sym->name, &a->expr->where);
> > -  else if (where)
> > -gfc_warning (OPT_Wargument_mismatch,
> > - "Character length mismatch (%ld/%ld) between
> > actual "
> > - "argument and assumed-shape dummy argument %qs "
> > - "at %L",
> > - mpz_get_si
> > (a->expr->ts.u.cl->length->value.integer),
> > - mpz_get_si
> > (f->sym->ts.u.cl->length->value.integer),
> > - f->sym->name, &a->expr->where);
> > -  return 0;
> > -}
> > + && a->expr->ts.u.cl && a->expr->ts.u.cl->length
> > + && a->expr->ts.u.cl->length->expr_type == EXPR_CONSTANT


> > + && f->sym->ts.type == BT_CHARACTER && f->sym->ts.u.cl

 ^^^

> > + && f->sym->ts.u.cl->length
> > + && f->sym->ts.u.cl->length->expr_type == EXPR_CONSTANT
> > + && (f->sym->attr.pointer || f->sym->attr.allocatable
> > + || (f->sym->as && f->sym->as->type == AS_ASSUMED_SHAPE))
> > + && (mpz_cmp (a->expr->ts.u.cl->length->value.integer,
> > +  f->sym->ts.u.cl->length->value.integer) != 0))
> > +   {



> > + && a->expr->ts.type == BT_CHARACTER)
> > {
> >   if (where)
> > gfc_error ("Actual argument at %L to allocatable or "  
> That one was just reformatting, right?

No, the check for the correct has been added at ^^^. I agree that reformatting
and the change was not a good idea. 

> 
> > @@ -3039,13 +3041,28 @@ compare_actual_formal (gfc_actual_arglist **ap,
> > gfc_formal_arglist *formal, return 0;
> > }
> >
> > +  /* Find the last array_ref.  */
> > +  actual_arr_ref = NULL;
> > +  if (a->expr->ref)
> > +   {
> > + gfc_ref *ref = a->expr->ref;
> > +
> > + do
> > +   {
> > + if (ref->type == REF_ARRAY)
> > +   actual_arr_ref = ref;
> > + ref

[RFC][PATCH] Sanopt for use-after-scope ASAN_MARK internal functions

2016-12-09 Thread Martin Liška
Hello.

I've spent quite some time reading sanopt pass and I eventually decided to come 
up
with quite simplified optimization algorithm for ASAN_MARK internal functions. 
As the
most interesting (common) cases are that an ASAN_MARK unpoison is dominated by 
entry
block (where we unpoison all variables). Second interesting situation is 
ASAN_MARK poison
which is not followed by a ASAN_CHECK (in post dominator tree). Both these 
internal functions
can be removed.

There are numbers for linux kernel (running for couple of minutes):

  20306 expand ASAN_MARK
   2892 Removing ASAN_MARK poison
   8124 Removing ASAN_MARK unpoison

This removes 1/3 of ASAN_MARK internal function call.

For tramp3d the situation is not so happy as it massively utilizes C++ 
temporaries:

  34163 expand ASAN_MARK
   1920 Removing ASAN_MARK poison
   2051 Removing ASAN_MARK unpoison

Thoughts?
Thanks,
Martin
>From c91ad7c9fa2406145467c473dc7239479635c9a2 Mon Sep 17 00:00:00 2001
From: marxin 
Date: Fri, 25 Nov 2016 15:05:33 +0100
Subject: [PATCH] Add sanopt for ASAN_MARK poison and unpoison.

---
 gcc/sanopt.c | 235 ++-
 1 file changed, 234 insertions(+), 1 deletion(-)

diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index 77307d9..a110db5 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -162,7 +162,6 @@ struct sanopt_ctx
   int asan_num_accesses;
 };
 
-
 /* Return true if there might be any call to free/munmap operation
on any path in between DOM (which should be imm(BB)) and BB.  */
 
@@ -671,6 +670,237 @@ public:
 
 }; // class pass_sanopt
 
+static void
+sanitize_asan_mark_unpoison (void)
+{
+  /* 1) Find all BBs that contain an ASAN_MARK poison call.  */
+  auto_sbitmap with_poison (last_basic_block_for_fn (cfun) + 1);
+  bitmap_clear (with_poison);
+  basic_block bb;
+
+  FOR_EACH_BB_FN (bb, cfun)
+{
+  if (bitmap_bit_p (with_poison, bb->index))
+	continue;
+
+  gimple_stmt_iterator gsi;
+  bool finish = false;
+  for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
+	{
+	  gimple *stmt = gsi_stmt (gsi);
+	  if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
+	{
+	  enum internal_fn ifn = gimple_call_internal_fn (stmt);
+	  switch (ifn)
+		{
+		case IFN_ASAN_MARK:
+		  {
+		HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (stmt, 0));
+		bool is_clobber = (flags & ASAN_MARK_CLOBBER) != 0;
+		if (is_clobber)
+		  {
+			bitmap_set_bit (with_poison, bb->index);
+			finish = true;
+		  }
+		break;
+		  }
+		  default:
+		break;
+		}
+	}
+
+	  if (finish)
+	break;
+	}
+}
+
+  auto_sbitmap poisoned (last_basic_block_for_fn (cfun) + 1);
+  bitmap_clear (poisoned);
+  auto_sbitmap worklist (last_basic_block_for_fn (cfun) + 1);
+  bitmap_copy (worklist, with_poison);
+
+  /* 2) Propagate the information to all reachable blocks.  */
+  while (!bitmap_empty_p (worklist))
+{
+  unsigned i = bitmap_first_set_bit (worklist);
+  bitmap_clear_bit (worklist, i);
+  basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
+  gcc_assert (bb);
+
+  edge e;
+  edge_iterator ei;
+  FOR_EACH_EDGE (e, ei, bb->succs)
+	if (!bitmap_bit_p (poisoned, e->dest->index))
+	  {
+	bitmap_set_bit (poisoned, e->dest->index);
+	bitmap_set_bit (worklist, e->dest->index);
+	  }
+}
+
+  /* 3) Iterate all BBs not included in POISONED BBs and remove unpoison
+	ASAN_MARK preceding an ASAN_MARK poison (which can still happen).  */
+  FOR_EACH_BB_FN (bb, cfun)
+{
+  if (bitmap_bit_p (poisoned, bb->index))
+	continue;
+
+  gimple_stmt_iterator gsi;
+  bool finish = false;
+  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+	{
+	  bool next = true;
+	  gimple *stmt = gsi_stmt (gsi);
+	  if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
+	{
+	  enum internal_fn ifn = gimple_call_internal_fn (stmt);
+	  switch (ifn)
+		{
+		case IFN_ASAN_MARK:
+		  {
+		HOST_WIDE_INT flags
+		  = tree_to_shwi (gimple_call_arg (stmt, 0));
+		bool is_clobber = (flags & ASAN_MARK_CLOBBER) != 0;
+		if (is_clobber)
+		  finish = true;
+		else
+		  {
+			if (dump_file)
+			  fprintf (dump_file, "Removing ASAN_MARK unpoison\n");
+			unlink_stmt_vdef (stmt);
+			gsi_remove (&gsi, true);
+			next = false;
+		  }
+		break;
+		  }
+		  default:
+		break;
+		}
+	}
+
+	  if (finish)
+	break;
+
+	  if (next)
+	gsi_next (&gsi);
+	}
+}
+}
+
+static bool
+maybe_contains_asan_check (gimple *stmt)
+{
+  if (is_gimple_call (stmt))
+{
+  if (gimple_call_internal_p (stmt))
+	{
+	  enum internal_fn ifn = gimple_call_internal_fn (stmt);
+	  switch (ifn)
+	{
+	case IFN_ASAN_CHECK:
+	  return true;
+	default:
+	  return false;
+	}
+	}
+  else
+return true;
+}
+  else if (is_a (stmt))
+return true;
+
+  return false;
+}
+
+static void
+sanitize_asan_mark_poison (void)
+{
+  /* 1) Find all BBs

Re: [PATCH] PR fortran/65173 -- kill off old_cl_list from gfc_namespace.

2016-12-09 Thread Paul Richard Thomas
Hi Steve,

In doing the final regtest of the fix for PR44265, I found that
charlen_15.f90 is still giving the original error for PR78350.

module.c:3419 is seeing (after continuing three times)
(gdb) print *e->ts.u.cl->length
$12 = {expr_type = 0, ts = {type = 81, kind = 0, u = {derived = 0x20ff570,
  cl = 0x20ff570, pad = 34600304}, interface = 0x20ff340,
is_c_interop = 0, is_iso_c = 0, f90_type = BT_UNKNOWN, deferred = false},
  rank = 0, shape = 0x20fe310, symtree = 0x0, ref = 0x0, where = {
nextc = 0x50, lb = 0x50}, base_expr = 0x20fe5e0, is_boz = 0, is_snan = 0,
  error = 0, user_operator = 0, mold = 0, must_finalize = 0, representation = {
length = 4096, string = 0x71a68000 "\002"}, value = {logical = 471,
iokind = 471, integer = {{_mp_alloc = 471, _mp_size = 0,
_mp_d = 0x410066}}, real = {{_mpfr_prec = 471, _mpfr_sign = 0,
_mpfr_exp = -1, _mpfr_d = 0x7f}}, complex = {{re = {{
_mpfr_prec = 471, _mpfr_sign = 0, _mpfr_exp = -1,
_mpfr_d = 0x7f}}, im = {{_mpfr_prec = 0, _mpfr_sign = 241,
_mpfr_exp = 214358001816, _mpfr_d = 0x2100100, op = {op = 471,
  uop = 0x410066, op1 = 0x, op2 = 0x7f},
function = {actual = 0x1d7,
  name = 0x410066 ,
  isym = 0x, esym = 0x7f}, compcall = {
  actual = 0x1d7,
  name = 0x410066 ,
  base_object = 0x, tbp = 0x7f, ignore_pass = 0,
  assign = 0}, character = {length = 471, string = 0x410066},
constructor = 0x1d7}}

It is the expr_type == = that causes the ICE in gfc_code2string.

Cheers

Paul

On 8 December 2016 at 22:33, Steve Kargl
 wrote:
> On Thu, Dec 08, 2016 at 07:58:37AM +0100, Paul Richard Thomas wrote:
>>
>> "Accidence" == state of fixing non-deterministic ICEs? :-)
>>
>> OK for trunk.
>>
>> Thanks for dealing with this kind of dead wood.
>>
>
> Committed revision 243463.
>
> --
> Steve



-- 
If you're walking down the right path and you're willing to keep
walking, eventually you'll make progress.

Barack Obama


Re: PR78634: ifcvt/i386 cost updates

2016-12-09 Thread Bernd Schmidt

On 12/03/2016 10:49 AM, Uros Bizjak wrote:


Based on the above explanation, the patch is OK.


I'll be treating the ifcvt part of it as obvious. However, testing 
showed an issue with the i386 funcspec-11 test:


/* PR target/36936 */
/* { dg-do compile } */
/* { dg-require-effective-target ia32 } */
/* { dg-options "-O2 -march=i386" } */
/* { dg-final { scan-assembler "cmov" } } */

extern int foo (int) __attribute__((__target__("arch=i686")));

int
foo (int x)
{
  if (x < 0)
x = 1;
  return x;
}

It wants to test that we can temporarily switch the arch, but we're 
still using the i386 cost table, with a branch cost of 1. This means the 
cmov now won't get generated for cost reasons.


It seems like whether we're generating cmov when tuning for i386 isn't 
the most critical thing to worry about, so I propose amending the test 
to also pass in -mtune=i686. Ok with that change?



Bernd


Re: [PATCH] PR fortran/65173 -- kill off old_cl_list from gfc_namespace.

2016-12-09 Thread Janne Blomqvist
On Fri, Dec 9, 2016 at 1:47 PM, Paul Richard Thomas
 wrote:
> Hi Steve,
>
> In doing the final regtest of the fix for PR44265, I found that
> charlen_15.f90 is still giving the original error for PR78350.
>
> module.c:3419 is seeing (after continuing three times)
> (gdb) print *e->ts.u.cl->length
> $12 = {expr_type = 0, ts = {type = 81, kind = 0, u = {derived = 0x20ff570,
>   cl = 0x20ff570, pad = 34600304}, interface = 0x20ff340,
> is_c_interop = 0, is_iso_c = 0, f90_type = BT_UNKNOWN, deferred = false},
>   rank = 0, shape = 0x20fe310, symtree = 0x0, ref = 0x0, where = {
> nextc = 0x50, lb = 0x50}, base_expr = 0x20fe5e0, is_boz = 0, is_snan = 0,
>   error = 0, user_operator = 0, mold = 0, must_finalize = 0, representation = 
> {
> length = 4096, string = 0x71a68000 "\002"}, value = {logical = 471,
> iokind = 471, integer = {{_mp_alloc = 471, _mp_size = 0,
> _mp_d = 0x410066}}, real = {{_mpfr_prec = 471, _mpfr_sign = 0,
> _mpfr_exp = -1, _mpfr_d = 0x7f}}, complex = {{re = {{
> _mpfr_prec = 471, _mpfr_sign = 0, _mpfr_exp = -1,
> _mpfr_d = 0x7f}}, im = {{_mpfr_prec = 0, _mpfr_sign = 241,
> _mpfr_exp = 214358001816, _mpfr_d = 0x2100100, op = {op = 471,
>   uop = 0x410066, op1 = 0x, op2 = 0x7f},
> function = {actual = 0x1d7,
>   name = 0x410066 ,
>   isym = 0x, esym = 0x7f}, compcall = {
>   actual = 0x1d7,
>   name = 0x410066 ,
>   base_object = 0x, tbp = 0x7f, ignore_pass = 0,
>   assign = 0}, character = {length = 471, string = 0x410066},
> constructor = 0x1d7}}
>
> It is the expr_type == = that causes the ICE in gfc_code2string.

I'm seeing the same thing, I guess. Or rather that the ts->type == 81
which is non-sensical. No idea where that comes from..

Backtrace from gdb:

#0  gfc_code2string (m=m@entry=0x182fe00 ,
code=code@entry=81) at ../../trunk-git/gcc/fortran/misc.c:193
#1  0x0065645f in mio_name (t=81, m=m@entry=0x182fe00
) at ../../trunk-git/gcc/fortran/module.c:1722
#2  0x0065acb9 in mio_name_bt (m=0x182fe00 ,
t=) at ../../trunk-git/gcc/fortran/module.c:2106
#3  mio_typespec (ts=ts@entry=0x2420918) at
../../trunk-git/gcc/fortran/module.c:2530
#4  0x0065ae50 in mio_expr (ep=0x24217d0) at
../../trunk-git/gcc/fortran/module.c:3432
#5  0x0065b300 in mio_charlen (clp=clp@entry=0x241fa80) at
../../trunk-git/gcc/fortran/module.c:2500
#6  0x0065ad50 in mio_typespec (ts=ts@entry=0x241fa78) at
../../trunk-git/gcc/fortran/module.c:2558
#7  0x0065ae50 in mio_expr (ep=ep@entry=0x24208a8) at
../../trunk-git/gcc/fortran/module.c:3432
#8  0x0065bb73 in mio_component (c=c@entry=0x2420830,
vtype=vtype@entry=0) at ../../trunk-git/gcc/fortran/module.c:2799
#9  0x0065bbdb in mio_component_list (cp=cp@entry=0x2422138,
vtype=0) at ../../trunk-git/gcc/fortran/module.c:2818
#10 0x0065c913 in mio_symbol (sym=sym@entry=0x2422090) at
../../trunk-git/gcc/fortran/module.c:4238
#11 0x0065cb8b in write_symbol (n=2, sym=sym@entry=0x2422090)
at ../../trunk-git/gcc/fortran/module.c:5613
#12 0x0065e87f in write_symbol0 (st=0x2422680) at
../../trunk-git/gcc/fortran/module.c:5653
#13 0x0065e7f2 in write_symbol0 (st=0x2420650) at
../../trunk-git/gcc/fortran/module.c:5632
#14 0x0065ea03 in write_module () at
../../trunk-git/gcc/fortran/module.c:5992
#15 0x0065ec59 in dump_module (name=name@entry=0x76853060
"m", dump_flag=dump_flag@entry=1) at
../../trunk-git/gcc/fortran/module.c:6120
#16 0x0065edf8 in gfc_dump_module (name=0x76853060 "m",
dump_flag=1) at ../../trunk-git/gcc/fortran/module.c:6163
#17 0x00675edd in gfc_parse_file () at
../../trunk-git/gcc/fortran/parse.c:6158
#18 0x006baa5b in gfc_be_parse_file () at
../../trunk-git/gcc/fortran/f95-lang.c:202
#19 0x00ce0456 in compile_file () at ../../trunk-git/gcc/toplev.c:463
#20 0x00ce240d in do_compile () at ../../trunk-git/gcc/toplev.c:1983
#21 0x00ce2934 in toplev::main
(this=this@entry=0x7fffd860, argc=argc@entry=13,
argv=argv@entry=0x7fffd968) at ../../trunk-git/gcc/toplev.c:2117
#22 0x016fc99c in main (argc=13, argv=0x7fffd968) at
../../trunk-git/gcc/main.c:39


>
> Cheers
>
> Paul
>
> On 8 December 2016 at 22:33, Steve Kargl
>  wrote:
>> On Thu, Dec 08, 2016 at 07:58:37AM +0100, Paul Richard Thomas wrote:
>>>
>>> "Accidence" == state of fixing non-deterministic ICEs? :-)
>>>
>>> OK for trunk.
>>>
>>> Thanks for dealing with this kind of dead wood.
>>>
>>
>> Committed revision 243463.
>>
>> --
>> Steve
>
>
>
> --
> If you're walking down the right path and you're willing to keep
> walking, eventually you'll make progress.
>
> Barack Obama



-- 
Janne Blomqvist


Re: [RFC][PATCH] Sanopt for use-after-scope ASAN_MARK internal functions

2016-12-09 Thread Jakub Jelinek
On Fri, Dec 09, 2016 at 12:39:24PM +0100, Martin Liška wrote:
> +   if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
> + {
> +   enum internal_fn ifn = gimple_call_internal_fn (stmt);
> +   switch (ifn)
> + {
> + case IFN_ASAN_MARK:
> +   {
> + HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (stmt, 
> 0));
> + bool is_clobber = (flags & ASAN_MARK_CLOBBER) != 0;
> + if (is_clobber)
> +   {
> + bitmap_set_bit (with_poison, bb->index);
> + finish = true;
> +   }
> + break;
> +   }
> +   default:
> + break;
> + }

This looks weird.  Wouldn't it be nicer to just use
  if (gimple_call_internal_fn (stmt) == IFN_ASAN_MARK)
{
  HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (stmt, 
0));
  bool is_clobber = (flags & ASAN_MARK_CLOBBER) != 0;
  if (is_clobber)
{
  bitmap_set_bit (with_poison, bb->index);
  finish = true;
}
}
(or don't use finish and just break; there)?
> +   enum internal_fn ifn = gimple_call_internal_fn (stmt);
> +   switch (ifn)
> + {
> + case IFN_ASAN_MARK:
> +   {

Likewise.

No function comment:

> +static bool
> +maybe_contains_asan_check (gimple *stmt)
> +{
> +  if (is_gimple_call (stmt))
> +{
> +  if (gimple_call_internal_p (stmt))
> + {
> +   enum internal_fn ifn = gimple_call_internal_fn (stmt);
> +   switch (ifn)
> + {
> + case IFN_ASAN_CHECK:
> +   return true;
> + default:
> +   return false;

Are all internal functions really known to be ASAN_CHECK free?

> + }
> + }
> +  else
> +return true;

What about builtins?  Many will not be fine, but many should be known
to be ASAN_CHECK free.  Consider e.g. most math builtins (except sincos).

> @@ -698,6 +928,9 @@ pass_sanopt::execute (function *fun)
>bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
>  && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
>  
> +  sanitize_asan_mark_unpoison ();
> +  sanitize_asan_mark_poison ();
> +

What I don't really like here is that you force several IL walks for all
sanitizers, just in case.  Look e.g. how asan_num_accesses is computed,
couldn't you compute similarly has_asan_marks and guard those two functions
on that?

Jakub


Re: [PATCH] DWARF: make signedness explicit for enumerator const values

2016-12-09 Thread Pierre-Marie de Rodat

On 11/18/2016 06:22 PM, Pierre-Marie de Rodat wrote:

I agree with you, so I’ll revise to instead add a DW_AT_type attribute
to enumeration DIEs to point to a base type.


Here is the patch to implement this. Bootstrapped and regtested (GCC’s 
testsuite) successfuly on x86_64-linux.


However, it is important to note that this creates a regression in GDB: 
in Ada, “ptype” of an array whose bounds are a subrange of an 
enumeration type gives something like:


array (0 .. 10) of integer

instead of the expected:

array (first_value .. last_value) of integer

We, at AdaCore, have a candidate GDB patch to fix this regression, but 
even if it gets upstream, this will affect all existing GDB versions. No 
other GDB regression otherwise.


--
Pierre-Marie de Rodat
>From bcc76900bdc0ec96d96a0a6290a3c21d1444e61b Mon Sep 17 00:00:00 2001
From: Pierre-Marie de Rodat 
Date: Fri, 9 Dec 2016 12:13:50 +0100
Subject: [PATCH] Ada/DWARF: add a DW_AT_type attribute to
 DW_TAG_enumeration_type

Currently, the DWARF description does not specify the signedness of the
representation of enumeration types.  This is a problem in some
contexts where DWARF consumers need to determine if value X is greater
than value Y.

For instance in Ada:

type Enum_Type is ( A, B, C, D);
for Enum_Type use (-1, 0, 1, 2);

type Rec_Type (E : Enum_Type) is record
   when A .. B => null;
   when others => B : Booleann;
end record;

The above can be described in DWARF the following way:

DW_TAG_enumeration_type(Enum_Type)
| DW_AT_byte_size: 1
  DW_TAG_enumerator(A)
  | DW_AT_const_value: -1
  DW_TAG_enumerator(B)
  | DW_AT_const_value: 0
  DW_TAG_enumerator(C)
  | DW_AT_const_value: 1
  DW_TAG_enumerator(D)
  | DW_AT_const_value: 2

DW_TAG_structure_type(Rec_Type)
  DW_TAG_member(E)
  | DW_AT_type: 
  DW_TAG_variant_part
  | DW_AT_discr: 
DW_TAG_variant
| DW_AT_discr_list: DW_DSC_range 0x7f 0
DW_TAG_variant
| DW_TAG_member(b)

DWARF consumers need to know that enumerators (A, B, C and D) are signed
in order to determine the set of E values for which Rec_Type has a B
field.  In practice, they need to know how to interpret the 0x7f LEB128
number above (-1, not 127).

There seems to be only two legal DWARF alternatives to solve this issue:
one is to add a DW_AT_type attribute to DW_TAG_enumerator_type DIEs to
make it point to a base type that specifies the signedness.  The other
is to make sure the form of the DW_AT_const_value attribute carries the
signedness information.

The first alternative is valid only starting with DWARF3. The second
alternative is valid will all versions of the DWARF standard, however it
removes the size information embedded in the form used to encode
DW_AT_const_value attributes (DW_FORM_data8/16/32).

This patch implements the first alternative.

gcc/

	* dwarf2out.h (gen_enumeration_type_die): If the selected DWARF
	standard allows it, add a DW_AT_type attribute for the
	enum's TREE_TYPE, if any.

gcc/ada/

	* gcc-interface/decl.c (gnat_to_gnu_entity): Assign a base type
	to enumeration types.
	* gcc-interface/misc.c (gnat_get_array_descr_info): Don't strip
	types in the bounds subrange type's TREE_TYPE chain if they
	bring information about the kind of integral type involved.
	* gcc-interface/utils.c (make_type_from_size): Likewise for the
	base types involved.
---
 gcc/ada/gcc-interface/decl.c  |  4 
 gcc/ada/gcc-interface/misc.c  |  6 --
 gcc/ada/gcc-interface/utils.c | 12 +++-
 gcc/dwarf2out.c   |  4 
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 9de85ef..961499d 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -1670,6 +1670,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	  if (!is_boolean)
 	TYPE_VALUES (gnu_type) = nreverse (gnu_list);
 
+	  /* Provide a base type so that in debug info, the enumeration type
+	 has signedness information associated.  */
+	  TREE_TYPE (gnu_type) = gnat_type_for_size (esize, is_unsigned);
+
 	  /* Note that the bounds are updated at the end of this function
 	 to avoid an infinite recursion since they refer to the type.  */
 	  goto discrete_type;
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 1fed72a..7eeec81 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -964,8 +964,10 @@ gnat_get_array_descr_info (const_tree const_type,
 	}
 
   /* The DWARF back-end will output BOUNDS_TYPE as the base type of
-	 the array index, so get to the base type of INDEX_TYPE.  */
-  while (TREE_TYPE (index_type))
+	 the array index.  All subtypes in the TREE_TYPE chain that just bring
+	 bounds can be ignored: strip them.  */
+  while (TREE_CODE (index_type) == INTEGER_TYPE
+	 && TREE_TYPE (index_type) != NULL_TREE)
 	

Re: Fold strstr (s, t) eq/ne s to strcmp (s, t) eq/ne 0 if strlen (t) is known

2016-12-09 Thread Prathamesh Kulkarni
On 7 December 2016 at 17:36, Jakub Jelinek  wrote:
> On Wed, Dec 07, 2016 at 05:02:46PM +0530, Prathamesh Kulkarni wrote:
>> +   if (arg1_len == NULL_TREE)
>> + {
>> +   gimple_stmt_iterator gsi;
>> +   tree strlen_decl;
>> +   gimple *strlen_call;
>> +
>> +   strlen_decl = builtin_decl_explicit 
>> (BUILT_IN_STRLEN);
>> +   strlen_call = gimple_build_call (strlen_decl, 1,
>> +arg1);
>> +   arg1_len = make_ssa_name (size_type_node);
>> +   gimple_call_set_lhs (strlen_call, arg1_len);
>> +   update_stmt (strlen_call);
>> +   gsi = gsi_for_stmt (call_stmt);
>> +   gsi_insert_before (&gsi, strlen_call, 
>> GSI_SAME_STMT);
>> + }
>
> Why?  If the strlen isn't readily available, do you really think it is
> always a win to replace one call with 2 calls?  The string you want to do
> strlen on can be huge, the haystack could be empty or very short, etc.
> I'd just punt if strlen isn't known.
>> +
>> +   gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
>> +   tree memcmp_decl = builtin_decl_explicit 
>> (BUILT_IN_MEMCMP);
>> +   gcall *memcmp_call
>> + = gimple_build_call (memcmp_decl, 3, arg0, arg1,
>> +  arg1_len);
>> +   tree memcmp_lhs = make_ssa_name (integer_type_node);
>> +   gimple_call_set_lhs (memcmp_call, memcmp_lhs);
>> +   update_stmt (memcmp_call);
>> +   gsi_remove (&gsi, true);
>> +   gsi_insert_before (&gsi, memcmp_call, GSI_SAME_STMT);
>> +
>> +   gsi = gsi_for_stmt (stmt);
>> +   tree zero = build_zero_cst (TREE_TYPE (memcmp_lhs));
>> +   gassign *ga = gimple_build_assign (lhs, code,
>> +  memcmp_lhs, zero);
>> +   gsi_replace (&gsi, ga, false);
>> +   update_ssa (TODO_update_ssa);
>
> And this is certainly even more wrong than the old TODO_update_ssa at the
> end of the pass, now you'll do it for every single replacement in the
> function.  Why do you need it?  The old call stmt has gimple_vdef and
> gimple_vuse, so just copy those over, see how e.g.
> replace_call_with_call_and_fold in gimple-fold.c does that.
> If you don't add strlen, you need to move the vdef/vuse from stmt to
> memcmp_call, if you really want to add strlen (see above note though),
> then that call should have a vuse added (same vuse as the stmt originally
> had).
Hi,
Thanks for the suggestions. In attached patch, I dropped the transform
if strlen (t) is unknown.
Since strstr is marked pure, so IIUC call_stmt for strstr shouldn't
have vdef assoicated with it ?
(gimple_vdef for call_stmt returned NULL for test-cases I tried it
with). Moving gimple_vuse
from call_stmt to memcmp_call worked for me.
Does the patch look OK ?
Bootstrap+tested on x86_64-unknown-linux-gnu with --enable-langauges=all,ada
Cross-tested on arm*-*-*, aarch64*-*-*.

Thanks,
Prathamesh
>
> Jakub
diff --git a/gcc/testsuite/gcc.dg/strlenopt-30.c 
b/gcc/testsuite/gcc.dg/strlenopt-30.c
new file mode 100644
index 000..329bc25
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-30.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-strlen" } */
+
+__attribute__((no_icf))
+_Bool f1(char *s)
+{
+  return __builtin_strstr (s, "hello") == s;
+}
+
+__attribute__((no_icf))
+_Bool f2(char *s)
+{
+  return s == __builtin_strstr (s, "hello");
+}
+
+__attribute__((no_icf))
+_Bool f3(char *s)
+{
+  return s != __builtin_strstr (s, "hello");
+}
+
+/* Do not perform transform, since strlen (t)
+   is unknown.  */
+
+__attribute__((no_icf))
+_Bool f4(char *s, char *t)
+{
+  return __builtin_strstr (s, t) == s;
+}
+
+/* Do not perform transform in this case, since
+   t1 doesn't have single use.  */
+
+__attribute__((no_icf))
+_Bool f5(char *s)
+{
+  void foo(char *);
+
+  char *t1 = __builtin_strstr (s, "hello");
+  foo (t1);
+  return (t1 == s);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_memcmp" 3 "strlen" } } */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 339812e..06b07b0 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -2302,7 +2302,81 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi)
  else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
handle_pointer_plus (gsi);
}
-  else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
+
+  /* Fold strstr (s, t) == s to memcmp (s, t, strlen (t)) == 0.
+

Re: [Patch, fortran] PR44265 - Link error with reference to parameter array in specification expression

2016-12-09 Thread Paul Richard Thomas
Dear All,

Following a discussion on #gfortran with Andre and Dominique the patch
has been committed without char_result_[16,17].f90 as revision 243478.

This has been one of the most ill-starred of any patch that I have
submitted. At the last moment, I found that char_result_14.f90 was
suffering from excess errors due to the introduction of
Wstringop-overflow at -O3. The odd thing is that this warning is not
explicitly available to fortran so it cannot be switched off. I
introduced this chunk to fix it:

*** gfc_trans_string_copy (stmtblock_t * blo
*** 6484,6493 
builtin_decl_explicit (BUILT_IN_MEMMOVE),
3, dest, src, slen);

tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
!   tmp4 = fill_with_spaces (tmp4, chartype,
!fold_build2_loc (input_location, MINUS_EXPR,
! TREE_TYPE(dlen), dlen, slen));

gfc_init_block (&tempblock);
gfc_add_expr_to_block (&tempblock, tmp3);
--- 6494,6511 
builtin_decl_explicit (BUILT_IN_MEMMOVE),
3, dest, src, slen);

+   /* Wstringop-overflow appears at -O3 even though this warning is not
+  explicitly available in fortran nor can it be switched off. If the
+  source length is a constant, its negative appears as a very large
+  postive number and triggers the warning in BUILTIN_MEMSET. Fixing
+  the result of the MINUS_EXPR suppresses this spurious warning.  */
+   tmp = fold_build2_loc (input_location, MINUS_EXPR,
+  TREE_TYPE(dlen), dlen, slen);
+   if (slength && TREE_CONSTANT (slength))
+ tmp = gfc_evaluate_now (tmp, block);
+
tmp4 = fold_build_pointer_plus_loc (input_location, dest, slen);
!   tmp4 = fill_with_spaces (tmp4, chartype, tmp);

gfc_init_block (&tempblock);
gfc_add_expr_to_block (&tempblock, tmp3);

I am changing the PR to reflect the continuing problem with Darwin.

Cheers

Paul


On 7 December 2016 at 22:50, Andre Vehreschild  wrote:
> Hi Paul,
>
> When you can narrow it down to only failing on Darwin, then filter the 
> testcases not to run on that system.
>
> - Andre
>
> Am 7. Dezember 2016 22:44:15 MEZ, schrieb Paul Richard Thomas 
> :
>>Dear Dominique,
>>
>>Thanks for the feedback. However, I don't know what to do about it.
>>Perhaps I should commit the patch without char_result_[16,17].f90 and
>>pass it on to somebody who is a bit more conversent with these issues?
>>As far as I am concerned, it is fixed on Linux.
>>
>>Any ideas anybody?
>>
>>Paul
>>
>>On 7 December 2016 at 20:11, Dominique d'Humières 
>>wrote:
>>> The tests gfortran.dg/char_result_16.f90 and
>>gfortran.dg/char_result_17.f90 fail with
>>>
>>> lto1: error: two or more sections for
>>.gnu.lto___get_PROC_names.3e3ee55b08747e7c
>>> lto1: internal compiler error: cannot read LTO decls from
>>/var/folders/8q/sh_swgz96r7f5vnn08f7fxr0gn/T//ccEJosbA.o
>>>
>>> This may be darwin specific as the linker is more picky than the
>>linux one.
>>>
>>> Dominique
>>>
 Le 7 déc. 2016 à 16:47, Paul Richard Thomas
>> a écrit :

 Dear Dominique,

 I will turn to the effect on PR77414 after committing the patch for
>>PR44265.

 The attached fixes the -flto problem. The chunk in
 trans-decl.c(gfc_finish_var_decl) did the job. It is quite obvious
>>now
 and, in fact, I am a bit surprised that the patch worked at all
 without the DECL_EXTERNAL.

 Bootstraps and regtests on FC21/x86_64 - OK for trunk?

 Paul

 2016-12-07  Paul Thomas  

PR fortran/44265
* gfortran.h : Add fn_result_spec bitfield to gfc_symbol.
* resolve.c (flag_fn_result_spec): New function.
(resolve_fntype): Call it for character result lengths.
* symbol.c (gfc_new_symbol): Set fn_result_spec to zero.
* trans-decl.c (gfc_sym_mangled_identifier): Include the
procedure name in the mangled name for symbols with the
fn_result_spec bit set.
(gfc_finish_var_decl): Mark the decls of these symbols
appropriately for the case where the function is external.
(gfc_get_symbol_decl): Mangle the name of these symbols.
(gfc_create_module_variable): Allow them through the assert.
(gfc_generate_function_code): Remove the assert before the
initialization of sym->tlink because the frontend no longer
uses this field.
* trans-expr.c (gfc_map_intrinsic_function): Add a case to
treat the LEN_TRIM intrinsic.

 2016-12-07  Paul Thomas  

PR fortran/44265
* gfortran.dg/char_result_14.f90: New test.
* gfortran.dg/char_result_15.f90: New test.
* gfortran.dg/char_result_16.f90: New test.
* gfortran.dg/char_result_17.f90: New test.


>>>
>
> --
> Andre Vehreschild * Kreuzherrenstr. 8 * 52062 Aachen
> Tel.: +49 241 929 10 18 * ve...@gmx.de



-- 
If you're walking down the right path and you're willing to kee

Re: [PR78365] ICE in determine_value_range, at tree-ssa-loo p-niter.c:413

2016-12-09 Thread Richard Biener
On Fri, Dec 9, 2016 at 11:51 AM, Martin Jambor  wrote:
> Hi,
>
> On Fri, Dec 09, 2016 at 03:36:44PM +1100, kugan wrote:
>> On 07/12/16 21:08, Martin Jambor wrote:
>> > On Mon, Nov 28, 2016 at 04:25:00PM +1100, kugan wrote:
>> >
>> > ...
>> >
>> > > Here is a patch that does this. To fox PR78365, in
>> > > ipa_get_callee_param_type, I am now checking DECL_ARGUMENTS first. I lto
>> > > bootstrapped and regression tested on x86_64-linux-gnu and ppc64le-linux
>> > > with no new regressions. I will build Firefox and measure the memory 
>> > > usage
>> > > as Honza suggested based on the feedback.
>> > >
>> >
>> > So, do you have any numbers?
>> I will do it. How do you measure the gcc's memory usage while building
>> Firefox. I saw Honza's LTO blog talks about using vmstat result. Any tips
>> please?
>
> I asked Martin Liska how he does it and he replied with:
>
>   Steps:
>
>   1) clone git repository: https://github.com/marxin/script-misc
>
>   2) Run command that does an LTO linking
>
>   3) ./system_top.py > /tmp/log
>   Run that in a separate terminal, terminate the script after the LTO linking
>   finishes.
>
>   4) ./vmstat_parser.py /tmp/log
>   Plot the collected data.
>
> so try that :-)   As far as I know, it uses vmstat.  Or maybe Honza
> has some other method.
>
>
>> > ...
>> >
>> > > -tree
>> > > +static tree
>> > >  ipa_get_callee_param_type (struct cgraph_edge *e, int i)
>> > >  {
>> > >int n;
>> > > +  tree t = e->callee ? DECL_ARGUMENTS (e->callee->decl) : NULL_TREE;
>> > > +  if (t)
>> > > +for (n = 0; n < i; n++)
>> > > +  {
>> > > + if (!t)
>> > > +   return NULL;
>> > > + t = TREE_CHAIN (t);
>> > > +  }
>> > > +  if (t)
>> > > +return TREE_TYPE (t);
>> > >tree type = (e->callee
>> > >  ? TREE_TYPE (e->callee->decl)
>> > >  : gimple_call_fntype (e->call_stmt));
>> > > -  tree t = TYPE_ARG_TYPES (type);
>> > > +  t = TYPE_ARG_TYPES (type);
>> >
>> > If TYPE_ARG_TYPES is inherently unreliable then I am afraid you must
>> > not fallback on it but rather return NULL if cs->callee is not
>> > available and adjust the caller to give up in that case.
>> >
>> > (I have checked both testcases that we hope to fix with types in jump
>> > functions and the gimple_call_fntype is the same as
>> > TREE_TYPE(e->callee->decl) so that does not help either).
>>
>> Do you like the attached patch where I have removed it.
>>
>
> I am fine with the new patch but you'll need an approval from Honza
> or Richi.
>
> I find it a bit saddening that we cannot really rely on
> gimple_call_fntype but at least I do not see any other way.

The patch looks somewhat backward.  It populates the param type from
the callee but the only thing we really know is the _originating_ type
from the callers DECL_ARGUMENTS (if the JF is based on a parameter
which is the only case where we do not know the type of the actual
value statically -- we only know the type we expect).

So the type would be present only on IPA_JF_PASS_THROUGH JFs
(? does that also cover modified params?).

At propagation time when applying the jump-function we have to make
sure to first convert the actual parameter value to that expected type
(or drop to BOTTOM if we can't do that conversion due to excess mismatches).

Richard.

> Thanks,
>
> Martin


Re: C++ PATCH to reject initializating flexible array members in constructors (PR c++/72775)

2016-12-09 Thread Marek Polacek
On Thu, Dec 08, 2016 at 01:42:44PM -0700, Martin Sebor wrote:
> On 12/08/2016 01:28 PM, Marek Polacek wrote:
> > On Thu, Dec 08, 2016 at 02:56:56PM -0500, Nathan Sidwell wrote:
> > > On 12/08/2016 01:05 PM, Jason Merrill wrote:
> > > > If the problem is the member initializer, we can diagnose that
> > > > directly rather than wait until we're in a constructor.
> > > 
> > > What about:
> > > struct Foo {
> > > int a;
> > > char ary[];
> > > Foo () : ary ("bob"){}
> > > };
> > > 
> > > ?  That ICEs in the same way.
> > 
> > My patch would make GCC to reject this too, but the new 'else' needs to
> > be removed from the patch, i.e.
> 
> Clang accepts this test case although it does reject the originally
> submitted test case with the messages below.  I think GCC should
> accept the latter case for compatibility.  If it is accepted then
> rejecting the original test case will make the array initialization
> irregular.  I think it would be nice if they both could accepted
> but I don't know how much work it would be to make it work.

It's likely late for that in any case.  I'd think we should fix the ICEs,
reject both, and maybe revisit the second case for GCC 8.

Marek


Re: Fold strstr (s, t) eq/ne s to strcmp (s, t) eq/ne 0 if strlen (t) is known

2016-12-09 Thread Jakub Jelinek
On Fri, Dec 09, 2016 at 05:36:41PM +0530, Prathamesh Kulkarni wrote:
> --- a/gcc/tree-ssa-strlen.c
> +++ b/gcc/tree-ssa-strlen.c
> @@ -2302,7 +2302,81 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi)
> else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
>   handle_pointer_plus (gsi);
>   }
> -  else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
> +
> +  /* Fold strstr (s, t) == s to memcmp (s, t, strlen (t)) == 0.
> +  if strlen (t) is known and var holding return value of strstr
> +  has single use.  */
> +
> +  else if (TREE_CODE (lhs) == SSA_NAME && INTEGRAL_TYPE_P (TREE_TYPE 
> (lhs)))
> + {
> +   enum tree_code code = gimple_assign_rhs_code (stmt);
> +   if (code == EQ_EXPR || code == NE_EXPR)

This way you handle _8 = _5 == _7;, but not if (_5 == _7) bar ();.  Shouldn't 
you
also handle GIMPLE_COND similarly (of course, the rhs1 and rhs2 grabbing
and code grabbing is different for GIMPLE_COND.  But the rest should be
the same, except again that you don't want to replace the GIMPLE_COND, but
adjust it.  Maybe also COND_EXPR in gimple_assign (_9 = _5 == _7 ? _10 : _11;).

> + {
> +   tree rhs1 = gimple_assign_rhs1 (stmt);
> +   tree rhs2 = gimple_assign_rhs2 (stmt);
> +   if (TREE_CODE (rhs1) == SSA_NAME
> +   && TREE_CODE (rhs2) == SSA_NAME)
> + {
> +   gcall *call_stmt = dyn_cast (SSA_NAME_DEF_STMT 
> (rhs1));
> +   if (!call_stmt)
> + {
> +   call_stmt = dyn_cast (SSA_NAME_DEF_STMT (rhs2));
> +   tree tmp = rhs1;
> +   rhs1 = rhs2;
> +   rhs2 = tmp;

We use std::swap (rhs1, rhs2); in this case these days.

> + }
> +
> +   tree call_lhs;
> +   if (call_stmt
> +   && gimple_call_builtin_p (call_stmt, BUILT_IN_STRSTR)
> +   && (call_lhs = gimple_call_lhs (call_stmt))
> +   && has_single_use (call_lhs))

This might not optimize if you have:
  _5 = foo ();
  _7 = __builtin_strstr (_5, "abcd");
  _8 = _5 == _7;

Or even you could have:
  _5 = __builtin_strstr (...);
  _7 = __builtin_strstr (_5, "abcd");
  _8 = _5 == _7;

So I wonder if you shouldn't do:
  gimple *call_stmt = NULL;
  for (int pass = 0; pass < 2; pass++)
{
  gimple *g = SSA_NAME_DEF_STMT (rhs1);
  if (gimple_call_builtin_p (g, BUILT_IN_STRSTR)
  && gimple_call_lhs (g) == rhs1
  && has_single_use (rhs1)
  && gimple_call_arg (g, 0) == rhs2)
{
  call_stmt = g;
  break;
}
  std::swap (rhs1, rhs2);
}
  if (call_stmt)
...

I think you don't need operand_equal_p, because SSA_NAMEs should just
be the same pointer if they are the same thing.
The above way you handle both orderings.  Perhaps also it is big enough to
be done in a separate function, which you call with the code/rhs1/rhs2 and
stmt for the EQ/NE_EXPR is_gimple_assign as well as for COND_EXPR and
GIMPLE_COND.

Jakub


Re: Ping [PATCH, Fortran, v1] Fix deallocation of nested derived typed components

2016-12-09 Thread Andre Vehreschild
Hi Jerry,

thanks for the review. Committed as r243480.

Regards,
Andre

On Thu, 8 Dec 2016 12:10:55 -0800
Jerry DeLisle  wrote:

> On 12/08/2016 05:42 AM, Andre Vehreschild wrote:
> > Ping!
> >
> > On Fri, 2 Dec 2016 13:28:40 +0100
> > Andre Vehreschild  wrote:
> >  
> >> Hi all,
> >>
> >> attached patch fixes on ICE, when freeing a scalar allocatable component
> >> in a derived typed coarray.
> >>
> >> Furthermore does it fix freeing of nested derived typed allocatable
> >> components. A simple code explains the bug that is solved by the patch:
> >>
> >> type inner
> >>   integer, allocatable :: i
> >> end type
> >> type outer
> >>   type(inner), allocatable :: link
> >> end type
> >>
> >> type(outer), allocatable :: obj
> >>
> >> allocate(obj)
> >> allocate(obj%link)
> >> allocate(obj%link%i)
> >>
> >> deallocate(obj%link)
> >> deallocate(obj) ! <- this will generate pseudo-pseudo-code of the kind:
> >>
> >> if (obj.link.i != 0)  // But link is already NULL, i.e. a crash occurs.
> >>   free(obj.link.i)
> >>
> >> The patch fixes this by moving the code for freeing link.i into the check
> >> if link is allocated, i.e.:
> >>
> >> if (obj.link != 0) {
> >>   if (obj.link.i != 0)  {
> >> free (obj.link.i);
> >> obj.link.i = 0;
> >>   }
> >>   free (obj.link);
> >>   obj.link = 0;
> >> }
> >>
> >> Furthermore does the patch ensure that the handle of an allocatable
> >> component is set to 0.
> >>
> >> Bootstraped and regtested ok on x86_64-linux/F23. Ok for trunk?
> >>
> >> Regards,
> >>Andre  
> >
> >  
> 
> I think OK.
> 
> Jerry


-- 
Andre Vehreschild * Email: vehre ad gmx dot de 
Index: gcc/fortran/ChangeLog
===
--- gcc/fortran/ChangeLog	(Revision 243479)
+++ gcc/fortran/ChangeLog	(Arbeitskopie)
@@ -1,3 +1,27 @@
+2016-12-09  Andre Vehreschild  
+
+	* trans-array.c (gfc_array_deallocate): Remove wrapper.
+	(gfc_trans_dealloc_allocated): Same.
+	(structure_alloc_comps): Restructure deallocation of (nested)
+	allocatable components.  Insert dealloc of sub-component into the block
+	guarded by the if != NULL for the component.
+	(gfc_trans_deferred_array): Use the almightly deallocate_with_status.
+	* trans-array.h: Remove prototypes.
+	* trans-expr.c (gfc_conv_procedure_call): Use the almighty deallocate_
+	with_status.
+	* trans-openmp.c (gfc_walk_alloc_comps): Likewise.
+	(gfc_omp_clause_assign_op): Likewise. 
+	(gfc_omp_clause_dtor): Likewise.
+	* trans-stmt.c (gfc_trans_deallocate): Likewise.
+	* trans.c (gfc_deallocate_with_status): Allow deallocation of scalar
+	and arrays as well as coarrays.
+	(gfc_deallocate_scalar_with_status): Get the data member for coarrays
+	only when freeing an array with descriptor.  And set correct caf_mode
+	when freeing components of coarrays.
+	* trans.h: Change prototype of gfc_deallocate_with_status to allow
+	adding statements into the block guarded by the if (pointer != 0) and
+	supply a coarray handle.
+
 2016-12-09  Paul Thomas  
 
 	PR fortran/44265
Index: gcc/fortran/trans-array.c
===
--- gcc/fortran/trans-array.c	(Revision 243479)
+++ gcc/fortran/trans-array.c	(Arbeitskopie)
@@ -5652,53 +5652,6 @@
 }
 
 
-/* Deallocate an array variable.  Also used when an allocated variable goes
-   out of scope.  */
-/*GCC ARRAYS*/
-
-tree
-gfc_array_deallocate (tree descriptor, tree pstat, tree errmsg, tree errlen,
-		  tree label_finish, gfc_expr* expr,
-		  int coarray_dealloc_mode)
-{
-  tree var;
-  tree tmp;
-  stmtblock_t block;
-  bool coarray = coarray_dealloc_mode != GFC_CAF_COARRAY_NOCOARRAY;
-
-  gfc_start_block (&block);
-
-  /* Get a pointer to the data.  */
-  var = gfc_conv_descriptor_data_get (descriptor);
-  STRIP_NOPS (var);
-
-  /* Parameter is the address of the data component.  */
-  tmp = gfc_deallocate_with_status (coarray ? descriptor : var, pstat, errmsg,
-errlen, label_finish, false, expr,
-coarray_dealloc_mode);
-  gfc_add_expr_to_block (&block, tmp);
-
-  /* Zero the data pointer; only for coarrays an error can occur and then
- the allocation status may not be changed.  */
-  tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
-			 var, build_int_cst (TREE_TYPE (var), 0));
-  if (pstat != NULL_TREE && coarray && flag_coarray == GFC_FCOARRAY_LIB)
-{
-  tree cond;
-  tree stat = build_fold_indirect_ref_loc (input_location, pstat);
-
-  cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
-			  stat, build_int_cst (TREE_TYPE (stat), 0));
-  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
-			 cond, tmp, build_empty_stmt (input_location));
-}
-
-  gfc_add_expr_to_block (&block, tmp);
-
-  return gfc_finish_block (&block);
-}
-
-
 /* Create an array constructor from an initialization expression.
We assume the frontend already did any expansions and conversions.  */
 
@@ -7806,39 +7759,6 @@
 }
 
 

Re: C++ PATCH to reject initializating flexible array members in constructors (PR c++/72775)

2016-12-09 Thread Nathan Sidwell

On 12/08/2016 03:42 PM, Martin Sebor wrote:

On 12/08/2016 01:28 PM, Marek Polacek wrote:

On Thu, Dec 08, 2016 at 02:56:56PM -0500, Nathan Sidwell wrote:



struct Foo {
int a;
char ary[];
Foo () : ary ("bob"){}



Clang accepts this test case although it does reject the originally
submitted test case with the messages below.  I think GCC should
accept the latter case for compatibility.  If it is accepted then
rejecting the original test case will make the array initialization
irregular.  I think it would be nice if they both could accepted
but I don't know how much work it would be to make it work.


I think all these should be rejected for the same reason -- they're 
equally unmeaningfull.  The string being used must be a string literal 
-- not a pointer to a caller-provided string, or template argument 
(which I could see as plausible use cases).  So the problem is being 
baked into the class or ctor definition.


nathan
--
Nathan Sidwell


Re: [Patch, Fortran, OOP] PR 61767: ICE in generate_finalization_wrapper at fortran/class.c:1491

2016-12-09 Thread Andre Vehreschild
Hi Janus,

yes, that was what I had in mind for the testcase. Now it looks ok to me.

- Andre

On Thu, 8 Dec 2016 16:41:23 +0100
Janus Weil  wrote:

> Hi Andre,
> 
> > so when I interpret the testcase correctly, than the finalizer should not be
> > called, right? So adding a call abort() in the Finalize and allocating and
> > deallocating M in the main program should do no harm, but make the testcase
> > IMO more feasible. What do you think?  
> 
> thanks for the comment. Indeed it can not hurt to extend it into a
> runtime test. New version attached (according to your suggestions). Ok
> with this?
> 
> Cheers,
> Janus
> 
> 
> 
> > On Thu, 8 Dec 2016 13:56:29 +0100
> > Janus Weil  wrote:
> >  
> >> Hi all,
> >>
> >> the attached patch fixes an ice-on-valid problem with finalization.
> >> The ICE turned out to be caused by a bug in 'has_finalizer_component':
> >> According to the documentation, this function is supposed to detect
> >> whether a derived type has any nonpointer nonallocatable components
> >> that have a finalizer. However it triggered also on pointer components
> >> with a finalizer. Fixing this makes the ICE go away.
> >>
> >> The patch regtests cleanly on x86_64-linux-gnu. Ok for trunk?
> >>
> >> Cheers,
> >> Janus
> >>
> >>
> >> 2016-12-08  Janus Weil  
> >>
> >> PR fortran/61767
> >> * class.c (has_finalizer_component): Fix this function to detect only
> >> non-pointer non-allocatable components which have a finalizer.
> >>
> >> 2016-12-08  Janus Weil  
> >>
> >> PR fortran/61767
> >> * gfortran.dg/finalize_31.f90: New test.  
> >
> >
> > --
> > Andre Vehreschild * Email: vehre ad gmx dot de  


-- 
Andre Vehreschild * Email: vehre ad gmx dot de 


[PATCH] Fix PR78699

2016-12-09 Thread Richard Biener

Fixing the cost model for large permuted SLP groups broke this due to
the excessive amount of garbage we create.  A previous fix for this
was (ab-)using the cost-model so this one simply makes a hard upper
bound for SLP group sizes.

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

Richard.

2016-12-09  Richard Biener  

PR tree-optimization/78699
* tree-vect-data-refs.c (vect_analyze_group_access_1): Limit
group size.

Index: gcc/tree-vect-data-refs.c
===
--- gcc/tree-vect-data-refs.c   (revision 243474)
+++ gcc/tree-vect-data-refs.c   (working copy)
@@ -2390,7 +2416,9 @@ vect_analyze_group_access_1 (struct data
   if (groupsize == 0)
 groupsize = count + gaps;
 
-  if (groupsize > UINT_MAX)
+  /* This could be UINT_MAX but as we are generating code in a very
+ inefficient way we have to cap earlier.  See PR78699 for example.  */
+  if (groupsize > 4096)
{
  if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,



Re: Ping [PATCH, Fortran, pr78505, v1] [F08] Coarray source allocation not synchronizing on oversubscribed cores

2016-12-09 Thread Andre Vehreschild
Hi Jerry,

thanks for the review. Committed as r243482.

Regards,
Andre

On Thu, 8 Dec 2016 12:12:02 -0800
Jerry DeLisle  wrote:

> On 12/08/2016 05:43 AM, Andre Vehreschild wrote:
> > Ping!
> >
> > On Fri, 2 Dec 2016 16:46:29 +0100
> > Andre Vehreschild  wrote:
> >  
> >> Hi all,
> >>
> >> attached patch adds a call to sync_all after an ALLOCATE allocating a
> >> coarray. This is to adhere to standard wanting:
> >>
> >> ..., execution of the segment (11.6.2) following the statement is delayed
> >> until all other active images in the current team have executed the same
> >> statement the same number of times in this team.
> >>
> >> This, esp. the "statement", means that assigning the SOURCE= is to come
> >> before the sync all, which means we have to do it explicitly after that
> >> assignment. Or the other way around the sync all can be done in library
> >> caf_register().
> >>
> >> Bootstraps and regtests ok on x86_64-linux/F23. Ok for trunk?
> >>
> >> Regards,
> >>Andre  
> >
> >  
> 
> This OK.
> 
> Jerry


-- 
Andre Vehreschild * Email: vehre ad gmx dot de 
Index: gcc/fortran/ChangeLog
===
--- gcc/fortran/ChangeLog	(Revision 243480)
+++ gcc/fortran/ChangeLog	(Arbeitskopie)
@@ -1,5 +1,11 @@
 2016-12-09  Andre Vehreschild  
 
+	PR fortran/78505
+	* trans-stmt.c (gfc_trans_allocate): Add sync all after the execution
+	of the whole allocate-statement to adhere to the standard.
+
+2016-12-09  Andre Vehreschild  
+
 	* trans-array.c (gfc_array_deallocate): Remove wrapper.
 	(gfc_trans_dealloc_allocated): Same.
 	(structure_alloc_comps): Restructure deallocation of (nested)
Index: gcc/fortran/trans-stmt.c
===
--- gcc/fortran/trans-stmt.c	(Revision 243480)
+++ gcc/fortran/trans-stmt.c	(Arbeitskopie)
@@ -5506,7 +5506,7 @@
   stmtblock_t block;
   stmtblock_t post;
   tree nelems;
-  bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set;
+  bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray ;
   gfc_symtree *newsym = NULL;
 
   if (!code->ext.alloc.list)
@@ -5516,6 +5516,7 @@
   expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
   label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
   e3_is = E3_UNSET;
+  is_coarray = false;
 
   gfc_init_block (&block);
   gfc_init_block (&post);
@@ -,9 +5556,10 @@
  expression.  */
   if (code->expr3)
 {
-  bool vtab_needed = false, temp_var_needed = false,
-	  is_coarray = gfc_is_coarray (code->expr3);
+  bool vtab_needed = false, temp_var_needed = false;
 
+  is_coarray = gfc_is_coarray (code->expr3);
+
   /* Figure whether we need the vtab from expr3.  */
   for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
 	   al = al->next)
@@ -6093,6 +6095,9 @@
 	  tree caf_decl, token;
 	  gfc_se caf_se;
 
+	  /* Set flag, to add synchronize after the allocate.  */
+	  is_coarray = true;
+
 	  gfc_init_se (&caf_se, NULL);
 
 	  caf_decl = gfc_get_tree_for_caf_expr (expr);
@@ -6114,6 +6119,11 @@
 	}
   else
 	{
+	  /* Allocating coarrays needs a sync after the allocate executed.
+	 Set the flag to add the sync after all objects are allocated.  */
+	  is_coarray = is_coarray || (gfc_caf_attr (expr).codimension
+  && flag_coarray == GFC_FCOARRAY_LIB);
+
 	  if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
 	  && expr3_len != NULL_TREE)
 	{
@@ -6357,6 +6367,15 @@
   gfc_add_modify (&block, se.expr, tmp);
 }
 
+  if (is_coarray && flag_coarray == GFC_FCOARRAY_LIB)
+{
+  /* Add a sync all after the allocation has been executed.  */
+  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
+ 3, null_pointer_node, null_pointer_node,
+ integer_zero_node);
+  gfc_add_expr_to_block (&post, tmp);
+}
+
   gfc_add_block_to_block (&block, &se.post);
   gfc_add_block_to_block (&block, &post);
 
Index: gcc/testsuite/ChangeLog
===
--- gcc/testsuite/ChangeLog	(Revision 243480)
+++ gcc/testsuite/ChangeLog	(Arbeitskopie)
@@ -1,5 +1,10 @@
 2016-12-09  Andre Vehreschild  
 
+	PR fortran/78505
+	* gfortran.dg/coarray_alloc_with_implicit_sync_1.f90: New test.
+
+2016-12-09  Andre Vehreschild  
+
 	* gfortran.dg/coarray_alloc_comp_3.f08: New test.
 	* gfortran.dg/coarray_alloc_comp_4.f08: New test.
 	* gfortran.dg/finalize_18.f90: Add count for additional guard against
Index: gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90
===
--- gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90	(nicht existent)
+++ gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90	(Arbeitskopie)
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original -fcoarray=lib" }
+! Check that allocating a coarray adds an implicit syn

[0/67] Add wrapper classes for machine_modes

2016-12-09 Thread Richard Sandiford
This series includes most of the changes in group C from:

https://gcc.gnu.org/ml/gcc/2016-11/msg00033.html

The idea is to add wrapper classes around machine_mode_enum
for specific groups of modes, such as scalar integers, scalar floats,
complex values, etc.  This has two main benefits: one specific to SVE
and one not.

The SVE-specific benefit is that it helps to introduce the concept
of variable-length vectors.  To do that we need to change the size
of a vector mode from being a known compile-time constant to being
(possibly) a run-time invariant.  We then need to do the same for
unconstrained machine_modes, which might or might not be vectors.
Introducing these new constrained types means that we can continue
to treat them as having a constant size.

The other benefit is that it uses static type checking to enforce
conditions that are easily forgotten otherwise.  The most common
sources of problems seem to be:

(a) using VOIDmode or BLKmode where a scalar integer was expected
(e.g. when getting the number of bits in the value).

(b) simplifying vector operations in ways that only make sense for
scalars.

The series helps with both of these, although we don't get the full
benefit of (b) until variable-sized modes are introduced.

I know of three specific cases in which the static type checking
forced fixes for things that turned out to be real bugs (although
we didn't know that at the time, otherwise we'd have posted patches).
They were later fixed for trunk by:

  https://gcc.gnu.org/ml/gcc-patches/2016-07/msg01783.html
  https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02983.html
  https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02896.html

The group C patches in ARM/sve-branch did slow compile time down a little.
I've since taken steps to avoid that:

- Make the tailcall pass handle aggregate parameters and return values
  (already in trunk).

- Turn some of the new wrapper functions into inline functions.

- Make all the machmode.h macros that used:

__builtin_constant_p (M) ? foo_inline (M) : foo_array[M[

  forward to an ALWAYS_INLINE function, so that (a) M is only evaluated
  once and (b) __builtin_constant_p is applied to a variable, and so is
  deferred until later passes.  This helped the optimisation to fire in
  more cases and to continue firing when M is a class rather than a
  raw enum.

- In a similar vein, make sure that conditions like:

 SImode == DImode

  are treated as builtin_constant_p by gencondmd, so that .md patterns
  with those conditions are dropped.

With these changes the series is actually a very slight compile-time win.
That might seem unlikely, but there are several possible reasons:

1. The machmode.h macro change above might allow more constant folding.

2. The series has a tendency to evaluate modes once, rather than
   continually fetching them from (sometimes quite deep) rtx nests.
   Refetching a mode is a particular problem if call comes between
   two uses, since the compiler then has to re-evaluate the whole thing.

3. The series introduces many uses of new SCALAR_*TYPE_MODE macros,
   as alternatives to TYPE_MODE.  The new macros avoid the usual:

 (VECTOR_TYPE_P (TYPE_CHECK (NODE)) \
  ? vector_type_mode (NODE) : (NODE)->type_common.mode)

   and become direct field accesses in release builds.

   VECTOR_TYPE_P would be consistently false for these uses,
   but call-clobbered registers would usually be treated as clobbered
   by the condition as a whole.

Maybe (3) is the most likely reason.

I tested this by compiling the testsuite for:

aarch64-linux-gnu alpha-linux-gnu arc-elf arm-linux-gnueabi
arm-linux-gnueabihf avr-elf bfin-elf c6x-elf cr16-elf cris-elf
epiphany-elf fr30-elf frv-linux-gnu ft32-elf h8300-elf
hppa64-hp-hpux11.23 ia64-linux-gnu i686-pc-linux-gnu
i686-apple-darwin iq2000-elf lm32-elf m32c-elf m32r-elf
m68k-linux-gnu mcore-elf microblaze-elf mips-linux-gnu
mipsisa64-linux-gnu mmix mn10300-elf moxie-rtems msp430-elf
nds32le-elf nios2-linux-gnu nvptx-none pdp11 powerpc-linux-gnuspe
powerpc-eabispe powerpc64-linux-gnu powerpc-ibm-aix7.0 rl78-elf
rx-elf s390-linux-gnu s390x-linux-gnu sh-linux-gnu sparc-linux-gnu
sparc64-linux-gnu sparc-wrs-vxworks spu-elf tilegx-elf tilepro-elf
xstormy16-elf v850-elf vax-netbsdelf visium-elf x86_64-darwin
x86_64-linux-gnu xtensa-elf

and checking that there were no changes in assembly.  Also tested
in the normal way on aarch64-linux-gnu and x86_64-linux-gnu.

The series depends on the already-posted:

  https://gcc.gnu.org/ml/gcc-patches/2016-11/msg01657.html

Sorry that this is so late, been distracted by other things.  Even if
we're too far into stage 3 for SVE itself to go in, I was hoping this
part (which was kind-of posted during stage 1) could go in independently.

Thanks,
Richard


[1/67] Add an E_ prefix to mode names and update case statements

2016-12-09 Thread Richard Sandiford
Later patches will add wrapper types for specific classes
of mode.  E.g. SImode will be a scalar_int_mode, SFmode will
be a scalar_float_mode, etc.  This patch prepares for that
change by adding an E_ prefix to the mode enum values.
It also adds #defines that map the unprefixed names
to the prefixed names; e.g:

  #define QImode (machine_mode (E_QImode))

Later patches will change this to use things like scalar_int_mode
where appropriate.

All case statements need to be updated to use the prefixed
names, since the unprefixed names will eventually not be
integer constant expressions.  This patch does a mechanical
substitution over the whole codebase.

gcc/
2016-11-23  Richard Sandiford  
Alan Hayward  
David Sherwood  

* genmodes.c (mode_size_inline): Add an E_ prefix to mode names.
(mode_nunits_inline): Likewise.
(mode_inner_inline): Likewise.
(mode_unit_size_inline): Likewise.
(mode_unit_precision_inline): Likewise.
(emit_insn_modes_h): Likewise.  Also emit a #define of the
unprefixed name.
(emit_mode_wider): Add an E_ prefix to mode names.
(emit_mode_complex): Likewise.
(emit_mode_inner): Likewise.
(emit_mode_adjustments): Likewise.
(emit_mode_int_n): Likewise.
* config/aarch64/aarch64-builtins.c (aarch64_simd_builtin_std_type):
Likewise.
* config/aarch64/aarch64-elf.h (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
* config/aarch64/aarch64.c (aarch64_split_simd_combine): Likewise.
(aarch64_split_simd_move): Likewise.
(aarch64_gen_storewb_pair): Likewise.
(aarch64_gen_loadwb_pair): Likewise.
(aarch64_gen_store_pair): Likewise.
(aarch64_gen_load_pair): Likewise.
(aarch64_get_condition_code_1): Likewise.
(aarch64_constant_pool_reload_icode): Likewise.
(get_rsqrte_type): Likewise.
(get_rsqrts_type): Likewise.
(get_recpe_type): Likewise.
(get_recps_type): Likewise.
(aarch64_gimplify_va_arg_expr): Likewise.
(aarch64_simd_container_mode): Likewise.
(aarch64_emit_load_exclusive): Likewise.
(aarch64_emit_store_exclusive): Likewise.
(aarch64_expand_compare_and_swap): Likewise.
(aarch64_gen_atomic_cas): Likewise.
(aarch64_emit_bic): Likewise.
(aarch64_emit_atomic_swap): Likewise.
(aarch64_emit_atomic_load_op): Likewise.
(aarch64_evpc_trn): Likewise.
(aarch64_evpc_uzp): Likewise.
(aarch64_evpc_zip): Likewise.
(aarch64_evpc_ext): Likewise.
(aarch64_evpc_rev): Likewise.
(aarch64_evpc_dup): Likewise.
(aarch64_gen_ccmp_first): Likewise.
(aarch64_gen_ccmp_next): Likewise.
* config/alpha/alpha.c (alpha_scalar_mode_supported_p): Likewise.
(alpha_emit_xfloating_libcall): Likewise.
(emit_insxl): Likewise.
(alpha_arg_type): Likewise.
* config/arc/arc.c (arc_vector_mode_supported_p): Likewise.
(arc_preferred_simd_mode): Likewise.
(arc_secondary_reload): Likewise.
(get_arc_condition_code): Likewise.
(arc_print_operand): Likewise.
* config/arc/arc.h (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
* config/arc/arc.md (casesi_load): Likewise.
(casesi_compact_jump): Likewise.
* config/arc/predicates.md (proper_comparison_operator): Likewise.
(cc_use_register): Likewise.
* config/arm/aout.h (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
* config/arm/arm-builtins.c (arm_simd_builtin_std_type): Likewise.
(arm_init_iwmmxt_builtins): Likewise.
* config/arm/arm.c (thumb1_size_rtx_costs): Likewise.
(neon_expand_vector_init): Likewise.
(arm_attr_length_move_neon): Likewise.
(maybe_get_arm_condition_code): Likewise.
(arm_emit_vector_const): Likewise.
(arm_preferred_simd_mode): Likewise.
(arm_output_iwmmxt_tinsr): Likewise.
(thumb1_output_casesi): Likewise.
(thumb2_output_casesi): Likewise.
(arm_emit_load_exclusive): Likewise.
(arm_emit_store_exclusive): Likewise.
(arm_expand_compare_and_swap): Likewise.
(arm_evpc_neon_vuzp): Likewise.
(arm_evpc_neon_vzip): Likewise.
(arm_evpc_neon_vrev): Likewise.
(arm_evpc_neon_vtrn): Likewise.
(arm_evpc_neon_vext): Likewise.
(arm_validize_comparison): Likewise.
* config/arm/neon.md (neon_vc): Likewise.
* config/avr/avr-c.c (avr_resolve_overloaded_builtin): Likewise.
* config/avr/avr.c (avr_rtx_costs_1): Likewise.
* config/c6x/c6x.c (c6x_vector_mode_supported_p): Likewise.
(c6x_preferred_simd_mode): Likewise.
* config/epiphany/epiphany.c (get_epiphany_condition_code):
Likewise.
(epiphany_rtx_costs): Likewise.
* config/epiphany/predicates.md (proper_comparison_operator):
Likewise.
* config/frv/frv.c (con

3 further backports to 6.3

2016-12-09 Thread Jakub Jelinek
Hi!

My tree-ssa-reassoc.c fix backport for 6 branch depends on 2 other patches,
where the testcases don't fail on the branch for those 2, but the issue has
been just latent.  Are these ok to backport to 6.3 too?

Bootstrapped/regtested on x86_64-linux and i686-linux.

Jakub
2016-12-09  Jakub Jelinek  

Backported from mainline
2016-09-21  Kugan Vivekanandarajah  

PR tree-optimization/72835
* tree-ssa-reassoc.c (make_new_ssa_for_def): New.
(make_new_ssa_for_all_defs): Likewise.
(zero_one_operation): Replace all SSA_NAMEs defined in the chain.

* gcc.dg/tree-ssa/pr72835.c: New test.

--- gcc/tree-ssa-reassoc.c  (revision 240298)
+++ gcc/tree-ssa-reassoc.c  (revision 240299)
@@ -1143,6 +1143,52 @@ decrement_power (gimple *stmt)
 }
 }
 
+/* Replace SSA defined by STMT and replace all its uses with new
+   SSA.  Also return the new SSA.  */
+
+static tree
+make_new_ssa_for_def (gimple *stmt)
+{
+  gimple *use_stmt;
+  use_operand_p use;
+  imm_use_iterator iter;
+  tree new_lhs;
+  tree lhs = gimple_assign_lhs (stmt);
+
+  new_lhs = make_ssa_name (TREE_TYPE (lhs));
+  gimple_set_lhs (stmt, new_lhs);
+
+  /* Also need to update GIMPLE_DEBUGs.  */
+  FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
+{
+  FOR_EACH_IMM_USE_ON_STMT (use, iter)
+   SET_USE (use, new_lhs);
+  update_stmt (use_stmt);
+}
+  return new_lhs;
+}
+
+/* Replace all SSAs defined in STMTS_TO_FIX and replace its
+   uses with new SSAs.  Also do this for the stmt that defines DEF
+   if *DEF is not OP.  */
+
+static void
+make_new_ssa_for_all_defs (tree *def, tree op,
+  vec &stmts_to_fix)
+{
+  unsigned i;
+  gimple *stmt;
+
+  if (*def != op
+  && TREE_CODE (*def) == SSA_NAME
+  && (stmt = SSA_NAME_DEF_STMT (*def))
+  && gimple_code (stmt) != GIMPLE_NOP)
+*def = make_new_ssa_for_def (stmt);
+
+  FOR_EACH_VEC_ELT (stmts_to_fix, i, stmt)
+make_new_ssa_for_def (stmt);
+}
+
 /* Find the single immediate use of STMT's LHS, and replace it
with OP.  Remove STMT.  If STMT's LHS is the same as *DEF,
replace *DEF with OP as well.  */
@@ -1181,6 +1227,9 @@ static void
 zero_one_operation (tree *def, enum tree_code opcode, tree op)
 {
   gimple *stmt = SSA_NAME_DEF_STMT (*def);
+  /* PR72835 - Record the stmt chain that has to be updated such that
+ we dont use the same LHS when the values computed are different.  */
+  auto_vec stmts_to_fix;
 
   do
 {
@@ -1190,8 +1239,12 @@ zero_one_operation (tree *def, enum tree
  && stmt_is_power_of_op (stmt, op))
{
  if (decrement_power (stmt) == 1)
-   propagate_op_to_single_use (op, stmt, def);
- return;
+   {
+ if (stmts_to_fix.length () > 0)
+   stmts_to_fix.pop ();
+ propagate_op_to_single_use (op, stmt, def);
+   }
+ break;
}
 
   name = gimple_assign_rhs1 (stmt);
@@ -1205,8 +1258,10 @@ zero_one_operation (tree *def, enum tree
{
  if (name == op)
name = gimple_assign_rhs2 (stmt);
+ if (stmts_to_fix.length () > 0)
+   stmts_to_fix.pop ();
  propagate_op_to_single_use (name, stmt, def);
- return;
+ break;
}
 
   /* We might have a multiply of two __builtin_pow* calls, and
@@ -1221,7 +1276,9 @@ zero_one_operation (tree *def, enum tree
{
  if (decrement_power (stmt2) == 1)
propagate_op_to_single_use (op, stmt2, def);
- return;
+ else
+   stmts_to_fix.safe_push (stmt2);
+ break;
}
}
 
@@ -1229,8 +1286,12 @@ zero_one_operation (tree *def, enum tree
   gcc_assert (name != op
  && TREE_CODE (name) == SSA_NAME);
   stmt = SSA_NAME_DEF_STMT (name);
+  stmts_to_fix.safe_push (stmt);
 }
   while (1);
+
+  if (stmts_to_fix.length () > 0)
+make_new_ssa_for_all_defs (def, op, stmts_to_fix);
 }
 
 /* Returns true if statement S1 dominates statement S2.  Like
--- gcc/testsuite/gcc.dg/tree-ssa/pr72835.c (revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr72835.c (revision 240299)
@@ -0,0 +1,37 @@
+/* PR tree-optimization/72835.  */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target int32plus } */
+
+struct struct_1 {
+unsigned int m1 : 6 ;
+unsigned int m2 : 24 ;
+unsigned int m3 : 6 ;
+};
+
+unsigned short var_32 = 0x2d10;
+
+struct struct_1 s1;
+
+void init ()
+{
+  s1.m1 = 4;
+  s1.m2 = 0x7ca4b8;
+  s1.m3 = 24;
+}
+
+void foo ()
+{
+  unsigned int c
+= ((unsigned int) s1.m2) * (-((unsigned int) s1.m3))
++ (var_32) * (-((unsigned int) (s1.m1)));
+  if (c != 4098873984)
+__builtin_abort ();
+}
+
+int main ()
+{
+init ();
+foo ();
+return 0;
+}
2016-12-09  Jakub Jelinek  

Backported from mainline
2016-09-26  Kugan Vivekanandarajah  

PR middle-end/7771

[2/67] Make machine_mode a class

2016-12-09 Thread Richard Sandiford
This patch renames enum machine_mode to enum machine_mode_enum
and adds a machine_mode wrapper class.

The previous patch mechanically replaced mode names in case
statements; this one updates other places that should continue
to use the enum directly.

The patch continues to use enums for static variables.  This isn't
necessary, but it cuts down on the amount of load-time initialisation
and shouldn't have any downsides.

The patch also changes things like:

  cmp_mode == DImode ? DFmode : DImode

to:

  cmp_mode == DImode ? E_DFmode : E_DImode

This is because DImode and DFmode will eventually be different
classes, so the original ?: wouldn't be well-formed.

The member functions of the new class are trivial and
heavily used.  There's not much point keeping them out-of-line
at -O0: if anything it would make debugging harder rather than
easier, and it would also slow things down.  The patch therefore
marks them as "always_inline", if that's available.

The patch continues to use enums for gencondmd.c, so that more
mode comparisons are integer constant expressions when checking
for always-true or always-false conditions.  This is the only
intended use of USE_ENUM_MODES.

The patch adds inline functions for all mode size properties,
with the macros being simple wrappers around them.  This is
necessary for the __builtin_constant_p trick to continue working
effectively when the mode arguments are slightly more complex
(but still foldable at compile time).

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* coretypes.h (machine_mode): New class.
* calls.c (emit_library_call_value_1): Cast to machine_mode_enum
instead of machine_mode.
* combine.c (reg_stat_type): Use machine_mode_enum and remove
ENUM_BITFIELD wrapper.
(undo): Likewise.
(simplify_if_then_else): Remove "enum" keywoard before "machine_mode".
* compare-elim.c (can_eliminate_compare): Likewise.
* config/aarch64/aarch64-builtins.c (v8qi_UP, v4hi_UP, v4hf_UP)
(v2si_UP, v2sf_UP, v1df_UP, di_UP, df_UP, v16qi_UP, v8hi_UP, v8hf_UP)
(v4si_UP, v4sf_UP, v2di_UP, v2df_UP, ti_UP, oi_UP, ci_UP, xi_UP)
(si_UP, sf_UP, hi_UP, hf_UP, qi_UP): Add E_ prefixes.
(CRC32_BUILTIN, ENTRY): Likewise.
(aarch64_simd_builtin_datum): Use machine_mode_enum instead of
machine_mode.
(aarch64_crc_builtin_datum): Likewise.
(aarch64_builtins): Likewise.
(aarch64_simd_builtin_std_type): Remove "enum" keyword
before "machine_mode".
(aarch64_lookup_simd_builtin_type): Likewise.
(aarch64_init_simd_builtin_types): Likewise.
(aarch64_simd_expand_args): Likewise.
* config/aarch64/aarch64-protos.h (aarch64_simd_attr_length_rglist):
Likewise.
(aarch64_reverse_mask): Likewise.
(aarch64_simd_emit_reg_reg_move): Likewise.
(aarch64_gen_adjusted_ldpstp): Likewise.
(aarch64_ccmp_mode_to_code): Likewise.
(aarch64_operands_ok_for_ldpstp): Likewise.
(aarch64_operands_adjust_ok_for_ldpstp): Likewise.
(simd_check_vect_par_cnst_half): Likewise.  Remove parameter names.
* config/aarch64/aarch64.c (aarch64_ira_change_pseudo_allocno_class):
Remove "enum" keyword before "machine_mode".
(aarch64_min_divisions_for_recip_mul): Likewise.
(aarch64_reassociation_width): Likewise.
(aarch64_get_condition_code_1): Likewise.
(aarch64_simd_emit_reg_reg_move): Likewise.
(aarch64_simd_attr_length_rglist): Likewise.
(aarch64_reverse_mask): Likewise.
(aarch64_operands_ok_for_ldpstp): Likewise.
(aarch64_operands_adjust_ok_for_ldpstp): Likewise.
(aarch64_gen_adjusted_ldpstp): Likewise.
(aarch64_push_regs): Add E_ prefixes to mode names.
(aarch64_pop_regs): Likewise.
(aarch64_process_components): Likewise.
* config/aarch64/aarch64.h (MACHMODE): Delete.
(CUMULATIVE_ARGS): Replace MACHMODE with machine_mode.
* config/aarch64/cortex-a57-fma-steering.c (fma_node::rename): Remove
"enum" keyword before "machine_mode".
* config/alpha/alpha.c (alpha_emit_conditional_move): Add E_ prefixes.
* config/arc/arc.c (arc_init_reg_tables): Cast to machine_mode_enum
rather than machine_mode.
(arc_legitimize_address_0): Likewise.
* config/arm/arm-builtins.c (arm_simd_builtin_std_type): Remove
"enum" keyword before "machine_mode".
(arm_lookup_simd_builtin_type): Likewise.
(arm_simd_builtin_type): Likewise.
(arm_init_simd_builtin_types): Likewise.
(arm_expand_neon_args): Likewise.
* config/arm/arm-protos.h (arm_expand_builtin): Likewise.
* config/avr/avr-log.c (avr_log_vadump): Cast to machine_mode_enum
rather than machine_mode.
* config/ft32/ft32.c (ft32_libcall_value): Remove "enum" keyword
before "m

[3/67] Add GDB pretty printer for machine mode classes

2016-12-09 Thread Richard Sandiford
This patch adds gdb hooks for printing machine_modes in the
natural way.

gcc/
* gdbhooks.py (MachineModePrinter): New class.
(build_pretty_printer): Use it for machine_modes.

diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
index 1212312..95f4b95 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -422,6 +422,16 @@ class VecPrinter:
 
 ##
 
+class MachineModePrinter:
+def __init__(self, gdbval):
+self.gdbval = gdbval
+
+def to_string (self):
+   name = str(self.gdbval['m_mode'])
+   return name[2:] if name.startswith('E_') else name
+
+##
+
 # TODO:
 #   * hashtab
 #   * location_t
@@ -518,6 +528,9 @@ def build_pretty_printer():
  'vec',
  VecPrinter)
 
+pp.add_printer_for_types(['machine_mode'],
+'machine_mode', MachineModePrinter)
+
 return pp
 
 gdb.printing.register_pretty_printer(



[4/67] Add FOR_EACH iterators for modes

2016-12-09 Thread Richard Sandiford
The new iterators are:

- FOR_EACH_MODE_IN_CLASS: iterate over all the modes in a mode class.

- FOR_EACH_MODE_FROM: iterate over all the modes in a class,
  starting at a given mode.

- FOR_EACH_WIDER_MODE: iterate over all the modes in a class,
  starting at the next widest mode after a given mode.

- FOR_EACH_2XWIDER_MODE: same, but considering only modes that
  are two times wider than the previous mode.

- FOR_EACH_MODE_UNTIL: iterate over all the modes in a class until
  a given mode is reached.

- FOR_EACH_MODE: iterate over all the modes in a class between
  two given modes, inclusive of the first but not the second.

These help with the stronger type checking added by later patches,
since every new mode will be in the same class as the previous one.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* machmode.h (machine_mode::from_int): New function.
(get_narrowest_mode): Likewise.
(mode_iterator::start): Likewise.
(mode_iterator::iterate_p): Likewise.
(mode_iterator::get_wider): Likewise.
(mode_iterator::get_known_wider): Likewise.
(mode_iterator::get_2xwider): Likewise.
(FOR_EACH_MODE_IN_CLASS): New mode iterator.
(FOR_EACH_MODE): Likewise.
(FOR_EACH_MODE_FROM): Likewise.
(FOR_EACH_MODE_UNTIL): Likewise.
(FOR_EACH_WIDER_MODE): Likewise.
(FOR_EACH_2XWIDER_MODE): Likewise.
* builtins.c (expand_builtin_strlen): Use new mode iterators.
* combine.c (simplify_comparison): Likewise
* config/i386/i386.c (type_natural_mode): Likewise.
* cse.c (cse_insn): Likewise.
* dse.c (find_shift_sequence): Likewise.
* emit-rtl.c (init_derived_machine_modes): Likewise.
(init_emit_once): Likewise.
* explow.c (hard_function_value): Likewise.
* expmed.c (init_expmed_one_mode): Likewise.
(extract_fixed_bit_field_1): Likewise.
(extract_bit_field_1): Likewise.
(expand_divmod): Likewise.
(emit_store_flag_1): Likewise.
* expr.c (init_expr_target): Likewise.
(convert_move): Likewise.
(alignment_for_piecewise_move): Likewise.
(widest_int_mode_for_size): Likewise.
(emit_block_move_via_movmem): Likewise.
(copy_blkmode_to_reg): Likewise.
(set_storage_via_setmem): Likewise.
(compress_float_constant): Likewise.
* omp-low.c (omp_clause_aligned_alignment): Likewise.
* optabs-query.c (get_best_extraction_insn): Likewise.
* optabs.c (expand_binop): Likewise.
(expand_twoval_unop): Likewise.
(expand_twoval_binop): Likewise.
(widen_leading): Likewise.
(widen_bswap): Likewise.
(expand_parity): Likewise.
(expand_unop): Likewise.
(prepare_cmp_insn): Likewise.
(prepare_float_lib_cmp): Likewise.
(expand_float): Likewise.
(expand_fix): Likewise.
(expand_sfix_optab): Likewise.
* postreload.c (move2add_use_add2_insn): Likewise.
* reg-stack.c (reg_to_stack): Likewise.
* reginfo.c (choose_hard_reg_mode): Likewise.
* rtlanal.c (init_num_sign_bit_copies_in_rep): Likewise.
* stmt.c (emit_case_decision_tree): Likewise.
* stor-layout.c (mode_for_size): Likewise.
(smallest_mode_for_size): Likewise.
(mode_for_vector): Likewise.
(finish_bitfield_representative): Likewise.
* tree-ssa-math-opts.c (target_supports_divmod_p): Likewise.
* tree-vect-generic.c (type_for_widest_vector_mode): Likewise.
* tree-vect-stmts.c (vectorizable_conversion): Likewise.
* var-tracking.c (prepare_call_arguments): Likewise.

gcc/ada/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* gcc-interface/misc.c (fp_prec_to_size): Use new mode iterators.
(fp_size_to_prec): Likewise.

gcc/c-family/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* c-common.c (c_common_fixed_point_type_for_size): Use new mode
iterators.
* c-cppbuiltin.c (c_cpp_builtins): Likewise.

diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index cef4b3a..4bb22ed 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -1280,8 +1280,7 @@ fp_prec_to_size (int prec)
 {
   machine_mode mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-   mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
 if (GET_MODE_PRECISION (mode) == prec)
   return GET_MODE_BITSIZE (mode);
 
@@ -1295,8 +1294,7 @@ fp_size_to_prec (int size)
 {
   machine_mode mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-   mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
 if (GET_MODE_BITSIZE (mode) == size)
   return GET_MODE_PR

[5/67] Small tweak to array_value_type

2016-12-09 Thread Richard Sandiford
Store the type mode in a variable so that a later,
more mechanical patch can change its type.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* tree-switch-conversion.c (array_value_type): Only read TYPE_MODE
once.  Use get_narrowest_mode instead of GET_CLASS_NARROWEST_MODE.

diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index b063c46..8b64f4b 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -945,15 +945,15 @@ array_value_type (gswitch *swtch, tree type, int num,
 {
   unsigned int i, len = vec_safe_length (info->constructors[num]);
   constructor_elt *elt;
-  machine_mode mode;
   int sign = 0;
   tree smaller_type;
 
   if (!INTEGRAL_TYPE_P (type))
 return type;
 
-  mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (TYPE_MODE (type)));
-  if (GET_MODE_SIZE (TYPE_MODE (type)) <= GET_MODE_SIZE (mode))
+  machine_mode type_mode = TYPE_MODE (type);
+  machine_mode mode = get_narrowest_mode (type_mode);
+  if (GET_MODE_SIZE (type_mode) <= GET_MODE_SIZE (mode))
 return type;
 
   if (len < (optimize_bb_for_size_p (gimple_bb (swtch)) ? 2 : 32))
@@ -991,7 +991,7 @@ array_value_type (gswitch *swtch, tree type, int num,
 
  mode = GET_MODE_WIDER_MODE (mode);
  if (mode == VOIDmode
- || GET_MODE_SIZE (mode) >= GET_MODE_SIZE (TYPE_MODE (type)))
+ || GET_MODE_SIZE (mode) >= GET_MODE_SIZE (type_mode))
return type;
}
 }



[6/67] Make GET_MODE_WIDER return an opt_mode

2016-12-09 Thread Richard Sandiford
GET_MODE_WIDER previously returned VOIDmode if no wider
mode exists.  That would cause problems with stricter mode
classes, since VOIDmode isn't for example a valid scalar
integer or floating-point mode.  This patch instead makes
it return a new opt_mode class, which holds either
a T or nothing.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* coretypes.h (opt_mode): New class.
* machmode.h (opt_mode): Likewise.
(opt_mode::else_void): New function.
(opt_mode::operator *): Likewise.
(opt_mode::exists): Likewise.
(GET_MODE_WIDER_MODE): Turn into a function and return an opt_mode.
(GET_MODE_2XWIDER_MODE): Likewise.
(mode_iterator::get_wider): Update accordingly.
(mode_iterator::get_2xwider): Likewise.
(mode_iterator::get_known_wider): Likewise, turning into a template.
* combine.c (make_extraction): Update use of GET_MODE_WIDER_MODE,
forcing a wider mode to exist.
* config/cr16/cr16.h (LONG_REG_P): Likewise.
* rtlanal.c (init_num_sign_bit_copies_in_rep): Likewise.
* config/c6x/c6x.c (c6x_rtx_costs): Update use of
GET_MODE_2XWIDER_MODE, forcing a wider mode to exist.
* lower-subreg.c (init_lower_subreg): Likewise.
* optabs-libfuncs.c (init_sync_libfuncs_1): Likewise, but not
on the final iteration.
* config/i386/i386.c (ix86_expand_set_or_movmem): Check whether
a wider mode exists before asking for a move pattern.
(get_mode_wider_vector): Update use of GET_MODE_WIDER_MODE,
forcing a wider mode to exist.
(expand_vselect_vconcat): Likewise GET_MODE_2XWIDER_MODE.
* config/ia64/ia64.c (expand_vselect_vconcat): Check whether
a 2x wider mode exists.
* config/mips/mips.c (mips_expand_vselect_vconcat): Likewise.
* expmed.c (init_expmed_one_mode): Update use of GET_MODE_WIDER_MODE.
Avoid checking for a MODE_INT if we already know the mode is not a
SCALAR_INT_MODE_P.
(extract_high_half): Update use of GET_MODE_WIDER_MODE,
forcing a wider mode to exist.
(expmed_mult_highpart_optab): Likewise.
(expmed_mult_highpart): Likewise.
* expr.c (expand_expr_real_2): Update use of GET_MODE_WIDER_MODE,
using else_void.
* lto-streamer-in.c (lto_input_mode_table): Likewise.
* optabs-query.c (find_widening_optab_handler_and_mode): Likewise.
* stor-layout.c (bit_field_mode_iterator::next_mode): Likewise.
* internal-fn.c (expand_mul_overflow): Update use of
GET_MODE_WIDER_MODE.
* tree-ssa-math-opts.c (convert_mult_to_widen): Likewise.
(convert_plusminus_to_widen): Likewise.
* omp-low.c (omp_clause_aligned_alignment): Likewise.
* tree-switch-conversion.c (array_value_type): Likewise.
* var-tracking.c (emit_note_insn_var_location): Likewise.
* tree-vrp.c (simplify_float_conversion_using_ranges): Likewise.
Return false inside rather than outside the loop if no wider mode
exists
* optabs.c (expand_binop): Update use of GET_MODE_WIDER_MODE
and GET_MODE_2XWIDER_MODE
(can_compare_p): Use else_void.

gcc/ada/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* gcc-interface/decl.c (validate_size): Update use of
GET_MODE_WIDER_MODE, forcing a wider mode to exist.

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 18ec63d..d3bee34 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -8528,7 +8528,7 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id 
gnat_object,
 {
   machine_mode p_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
   while (!targetm.valid_pointer_mode (p_mode))
-   p_mode = GET_MODE_WIDER_MODE (p_mode);
+   p_mode = *GET_MODE_WIDER_MODE (p_mode);
   type_size = bitsize_int (GET_MODE_BITSIZE (p_mode));
 }
 
diff --git a/gcc/combine.c b/gcc/combine.c
index 8b08b14..e8e0b3f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7592,10 +7592,7 @@ make_extraction (machine_mode mode, rtx inner, 
HOST_WIDE_INT pos,
   wanted_inner_mode = smallest_mode_for_size (len, MODE_INT);
   while (pos % GET_MODE_BITSIZE (wanted_inner_mode) + len
 > GET_MODE_BITSIZE (wanted_inner_mode))
-   {
- wanted_inner_mode = GET_MODE_WIDER_MODE (wanted_inner_mode);
- gcc_assert (wanted_inner_mode != VOIDmode);
-   }
+   wanted_inner_mode = *GET_MODE_WIDER_MODE (wanted_inner_mode);
 }
 
   orig_pos = pos;
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index fcb5b01..7e059b2 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -6063,7 +6063,7 @@ c6x_rtx_costs (rtx x, machine_mode mode, int outer_code, 
int opno, int *total,
   /* Recognize a mult_highpart operation.  */
   if ((mode == HImod

Re: Pretty printers for versioned namespace

2016-12-09 Thread François Dumont

On 02/12/2016 01:41, Jonathan Wakely wrote:

On 01/12/16 22:51 +0100, François Dumont wrote:
We needed the StdExpVerAnyPrinter just because of the loopkup for 
'std::string' which has to be 'std::__7::string'. But I used similar 
technique exposed previously to get rid of it.


But I don't see any std::__7::string in the relevant symbols. Here's
the manager function for an std:experimental::__7::any storing a
std::__7::string:

std::experimental::fundamentals_v1::__7::any::_Manager_internalstd::__7::char_traits, std::__7::allocator > 
>::_S_manage(std::experimental::fundamentals_v1::__7::any::_Op, 
>std::experimental::fundamentals_v1::__7::any const*, 
>std::experimental::fundamentals_v1::__7::any::_Arg*)


Since this has no std::__7::string it doesn't need to be substituted.

Do any tests fail without the change to StdExpAnyPrinter? Which ones?



Yes, tests involving std::any are failing because of the std::string lookup:

Python Exception  No type named std::string.:
skipping: Python Exception  No type named std::string.:
Python Exception  No type named std::string.:
$9 = {_M_manager = 0x4046f4 
::_S_manage(std::__7::any::_Op, 
std::__7::any const*, std::__7::any::_Arg*)>, _M_storage = {_M_ptr = 
0x0skipping:

Python Exception  No type named std::string.:
, _M_buffer = {__data = "\000\000\000\000\000\000\000", __align = {data fields>
got: $9 = {_M_manager = 0x4046f4 
::_S_manage(std::__7::any::_Op, 
std::__7::any const*, std::__7::any::_Arg*)>, _M_storage = {_M_ptr = 
0x0, _M_
buffer = {__data = "\000\000\000\000\000\000\000", __align = {fields>

FAIL: libstdc++-prettyprinters/cxx17.cc print ab

This lookup is needed to correctly handle std::any. As 
stated in the comment:


# FIXME need to expand 'std::string' so that 
gdb.lookup_type works


But I don't know how to fix this so for the moment I just adapt it to 
correctly handle std::__7::string.


Here is my latest version tested with an without version namespace.

Ok to commit ?

François

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index ff428e8..f2d5632 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -36,6 +36,8 @@ import sys
 # We probably can't do much about this until this GDB PR is addressed:
 # 
 
+vers_nsp = '__7::'
+
 if sys.version_info[0] > 2:
 ### Python 3 stuff
 Iterator = object
@@ -127,9 +129,9 @@ class UniquePointerPrinter:
 
 def to_string (self):
 impl_type = self.val.type.fields()[0].type.tag
-if impl_type.startswith('std::__uniq_ptr_impl<'): # New implementation
+if re.match('^std::(' + vers_nsp + ')?__uniq_ptr_impl<.*>$', impl_type): # New implementation
 v = self.val['_M_t']['_M_t']['_M_head_impl']
-elif impl_type.startswith('std::tuple<'):
+elif re.match('^std::(' + vers_nsp + ')?tuple<.*>$', impl_type):
 v = self.val['_M_t']['_M_head_impl']
 else:
 raise ValueError("Unsupported implementation for unique_ptr: %s" % self.val.type.fields()[0].type.tag)
@@ -485,7 +487,10 @@ class StdRbtreeIteratorPrinter:
 def __init__ (self, typename, val):
 self.val = val
 valtype = self.val.type.template_argument(0).strip_typedefs()
-nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
+if typename.startswith('std::' + vers_nsp):
+nodetype = gdb.lookup_type('std::' + vers_nsp + '_Rb_tree_node<' + str(valtype) + '>')
+else:
+nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
 self.link_type = nodetype.strip_typedefs().pointer()
 
 def to_string (self):
@@ -927,7 +932,6 @@ class SingleObjContainerPrinter(object):
 return self.visualizer.display_hint ()
 return self.hint
 
-
 class StdExpAnyPrinter(SingleObjContainerPrinter):
 "Print a std::any or std::experimental::any"
 
@@ -948,7 +952,11 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
 raise ValueError("Unknown manager function in %s" % self.typename)
 
 # FIXME need to expand 'std::string' so that gdb.lookup_type works
-mgrname = re.sub("std::string(?!\w)", str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1))
+if typename.startswith('std::' + vers_nsp):
+strt = gdb.lookup_type('std::' + vers_nsp + 'string')
+else:
+strt = gdb.lookup_type('std::string')
+mgrname = re.sub("std::string(?!\w)", str(strt.strip_typedefs()), m.group(1))
 mgrtype = gdb.lookup_type(mgrname)
 self.contained_type = mgrtype.template_argument(0)
 valptr = None
@@ -1031,7 +1039,7 @@ class StdNodeHandlePrinter(SingleObjContainerPrinter):
 def __init__(self, typename, val):
 self.value_type = val.type.template_argument(1)
 

Re: 3 further backports to 6.3

2016-12-09 Thread Richard Biener
On Fri, 9 Dec 2016, Jakub Jelinek wrote:

> Hi!
> 
> My tree-ssa-reassoc.c fix backport for 6 branch depends on 2 other patches,
> where the testcases don't fail on the branch for those 2, but the issue has
> been just latent.  Are these ok to backport to 6.3 too?

Yes.

Thanks,
Richard.


[7/67] Add scalar_float_mode

2016-12-09 Thread Richard Sandiford
This patch adds a scalar_float_mode class, which wraps a mode enum
that is known to satisfy SCALAR_FLOAT_MODE_P.  Things like "SFmode"
now give a scalar_float_mode object instead of a machine_mode.
This in turn needs a change to the real.h format_helper, so that
it can accept both machine_modes and scalar_float_modes.

gcc/
2016-11-30  Richard Sandiford  
Alan Hayward  
David Sherwood  

* coretypes.h (scalar_float_mode): New type.
* machmode.h (PROTECT_ENUM_CONVERSION): New macro.
(is_a): New function.
(as_a): Likewise.
(dyn_cast): Likewise.
(scalar_float_mode): New class.
(scalar_float_mode::includes_p): New function.
(scalar_float_mode::from_int): Likewise.
* real.h (FLOAT_MODE_FORMAT): Use as_a .
(format_helper::format_helper): Turn into a template.
* genmodes.c (get_mode_class): New function.
(emit_insn_modes_h): Give modes the class returned by get_mode_class,
or machine_mode if none.
* config/aarch64/aarch64.c (aarch64_simd_valid_immediate): Use
as_a .
* dwarf2out.c (mem_loc_descriptor): Likewise.
(insert_float): Likewise.
(add_const_value_attribute): Likewise.
* simplify-rtx.c (simplify_immed_subreg): Likewise.
* optabs.c (expand_absneg_bit): Take a scalar_float_mode.
(expand_unop): Update accordingly.
(expand_abs_nojump): Likewise.
(expand_copysign_absneg): Take a scalar_float_mode.
(expand_copysign_bit): Likewise.
(expand_copysign): Update accordingly.

gcc/ada/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* gcc-interface/utils.c (gnat_type_for_mode): Use is_a
 instead of SCALAR_FLOAT_MODE_P.

diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 0ae381f..29e5203 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -3411,8 +3411,10 @@ gnat_type_for_mode (machine_mode mode, int unsignedp)
   if (COMPLEX_MODE_P (mode))
 return NULL_TREE;
 
-  if (SCALAR_FLOAT_MODE_P (mode))
-return float_type_for_precision (GET_MODE_PRECISION (mode), mode);
+  scalar_float_mode float_mode;
+  if (is_a  (mode, &float_mode))
+return float_type_for_precision (GET_MODE_PRECISION (float_mode),
+float_mode);
 
   if (SCALAR_INT_MODE_P (mode))
 return gnat_type_for_size (GET_MODE_BITSIZE (mode), unsignedp);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 944577d..cc97b7a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -11035,8 +11035,12 @@ aarch64_simd_valid_immediate (rtx op, machine_mode 
mode, bool inverse,
 
   if (info)
{
- info->value = CONST_VECTOR_ELT (op, 0);
- info->element_width = GET_MODE_BITSIZE (GET_MODE (info->value));
+ rtx elt = CONST_VECTOR_ELT (op, 0);
+ scalar_float_mode elt_mode
+   = as_a  (GET_MODE (elt));
+
+ info->value = elt;
+ info->element_width = GET_MODE_BITSIZE (elt_mode);
  info->mvn = false;
  info->shift = 0;
}
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 9f81995..f4c1859 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -56,6 +56,7 @@ struct rtx_def;
 typedef struct rtx_def *rtx;
 typedef const struct rtx_def *const_rtx;
 class machine_mode;
+class scalar_float_mode;
 template class opt_mode;
 
 /* Subclasses of rtx_def, using indentation to show the class
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 8dc8523..5130b64 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -15121,7 +15121,8 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
  else
 #endif
{
- unsigned int length = GET_MODE_SIZE (mode);
+ scalar_float_mode float_mode = as_a  (mode);
+ unsigned int length = GET_MODE_SIZE (float_mode);
  unsigned char *array = ggc_vec_alloc (length);
 
  insert_float (rtl, array);
@@ -18343,11 +18344,12 @@ insert_float (const_rtx rtl, unsigned char *array)
 {
   long val[4];
   int i;
+  scalar_float_mode mode = as_a  (GET_MODE (rtl));
 
-  real_to_target (val, CONST_DOUBLE_REAL_VALUE (rtl), GET_MODE (rtl));
+  real_to_target (val, CONST_DOUBLE_REAL_VALUE (rtl), mode);
 
   /* real_to_target puts 32-bit pieces in each long.  Pack them.  */
-  for (i = 0; i < GET_MODE_SIZE (GET_MODE (rtl)) / 4; i++)
+  for (i = 0; i < GET_MODE_SIZE (mode) / 4; i++)
 {
   insert_int (val[i], 4, array);
   array += 4;
@@ -18391,21 +18393,19 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
 floating-point constant.  A CONST_DOUBLE is used whenever the
 constant requires more than one word in order to be adequately
 represented.  */
-  {
-   machine_mode mode = GET_MODE (rtl);
-
-   if (TARGET_SUPPORTS_WIDE_INT == 0 && !SCALAR_

[8/67] Simplify gen_trunc/extend_conv_libfunc

2016-12-09 Thread Richard Sandiford
Replace checks of:

  GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode)

with !is_a  and use MODE_CLASS equality/inequality
instead of:

  (GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
  || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (tmode))

and:

  (GET_MODE_CLASS (tmode) == MODE_FLOAT
   && GET_MODE_CLASS (fmode) == MODE_FLOAT)
  || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode))

gcc/
2016-11-30  Richard Sandiford  
Alan Hayward  
David Sherwood  

* optabs-libfuncs.c (gen_trunc_conv_libfunc): Use is_a
 .  Simplify.
(gen_extend_conv_libfunc): Likewise.

diff --git a/gcc/optabs-libfuncs.c b/gcc/optabs-libfuncs.c
index 9d9ffbd..75fd677 100644
--- a/gcc/optabs-libfuncs.c
+++ b/gcc/optabs-libfuncs.c
@@ -579,24 +579,20 @@ gen_trunc_conv_libfunc (convert_optab tab,
machine_mode tmode,
machine_mode fmode)
 {
-  if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
-return;
-  if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
-return;
-  if (tmode == fmode)
+  scalar_float_mode float_tmode, float_fmode;
+  if (!is_a  (fmode, &float_fmode)
+  || !is_a  (tmode, &float_tmode)
+  || float_tmode == float_fmode)
 return;
 
-  if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
-  || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P 
(tmode)))
- gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
+  if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode))
+gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
 
-  if (GET_MODE_PRECISION (fmode) <= GET_MODE_PRECISION (tmode))
+  if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode))
 return;
 
-  if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
-   && GET_MODE_CLASS (fmode) == MODE_FLOAT)
-  || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
-gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
+  if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode))
+gen_intraclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
 }
 
 /* Pick proper libcall for extend_optab.  We need to chose if we do
@@ -608,23 +604,19 @@ gen_extend_conv_libfunc (convert_optab tab,
 machine_mode tmode,
 machine_mode fmode)
 {
-  if (GET_MODE_CLASS (tmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (tmode))
-return;
-  if (GET_MODE_CLASS (fmode) != MODE_FLOAT && !DECIMAL_FLOAT_MODE_P (fmode))
-return;
-  if (tmode == fmode)
+  scalar_float_mode float_tmode, float_fmode;
+  if (!is_a  (fmode, &float_fmode)
+  || !is_a  (tmode, &float_tmode)
+  || float_tmode == float_fmode)
 return;
 
-  if ((GET_MODE_CLASS (tmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P (fmode))
-  || (GET_MODE_CLASS (fmode) == MODE_FLOAT && DECIMAL_FLOAT_MODE_P 
(tmode)))
- gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
+  if (GET_MODE_CLASS (float_tmode) != GET_MODE_CLASS (float_fmode))
+gen_interclass_conv_libfunc (tab, opname, float_tmode, float_fmode);
 
-  if (GET_MODE_PRECISION (fmode) > GET_MODE_PRECISION (tmode))
+  if (GET_MODE_PRECISION (float_fmode) > GET_MODE_PRECISION (float_tmode))
 return;
 
-  if ((GET_MODE_CLASS (tmode) == MODE_FLOAT
-   && GET_MODE_CLASS (fmode) == MODE_FLOAT)
-  || (DECIMAL_FLOAT_MODE_P (fmode) && DECIMAL_FLOAT_MODE_P (tmode)))
+  if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode))
 gen_intraclass_conv_libfunc (tab, opname, tmode, fmode);
 }
 



[9/67] Add SCALAR_FLOAT_TYPE_MODE

2016-12-09 Thread Richard Sandiford
This patch adds a macro that extracts the TYPE_MODE and forcibly
converts it to a scalar_float_mode.  The forcible conversion
includes a gcc_checking_assert that the mode is a SCALAR_FLOAT_MODE_P.

This becomes important as more static type checking is added by
later patches.  It has the additional benefit of bypassing the
VECTOR_TYPE_P (...) ? vector_type_mode (...) : ... condition
in TYPE_MODE; in release builds the new macro is a simple
field access.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* tree.h (SCALAR_FLOAT_TYPE_MODE): New macro.
* builtins.c (expand_builtin_signbit): Use it instead of TYPE_MODE.
* fold-const.c (fold_convert_const_real_from_fixed): Likewise.
(native_encode_real): Likewise.
(native_interpret_real): Likewise.
* hsa-brig.c (emit_immediate_scalar_to_buffer): Likewise.
* tree-vrp.c (simplify_float_conversion_using_ranges): Likeiwse.

gcc/cp/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* mangle.c (write_real_cst): Use SCALAR_FLOAT_TYPE_MODE
instead of TYPE_MODE.

gcc/fortran/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* target-memory.c (size_float): Use SCALAR_FLOAT_TYPE_MODE
instead of TYPE_MODE.

gcc/objc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* objc-encoding.c (encode_type): Use SCALAR_FLOAT_TYPE_MODE
instead of TYPE_MODE.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 1f942b3..6de9a33 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5210,7 +5210,8 @@ static rtx
 expand_builtin_signbit (tree exp, rtx target)
 {
   const struct real_format *fmt;
-  machine_mode fmode, imode, rmode;
+  scalar_float_mode fmode;
+  machine_mode imode, rmode;
   tree arg;
   int word, bitpos;
   enum insn_code icode;
@@ -5221,7 +5222,7 @@ expand_builtin_signbit (tree exp, rtx target)
 return NULL_RTX;
 
   arg = CALL_EXPR_ARG (exp, 0);
-  fmode = TYPE_MODE (TREE_TYPE (arg));
+  fmode = SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (arg));
   rmode = TYPE_MODE (TREE_TYPE (exp));
   fmt = REAL_MODE_FORMAT (fmode);
 
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 4fffe0b..3cccb4f 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1795,7 +1795,7 @@ write_real_cst (const tree value)
   int i, limit, dir;
 
   tree type = TREE_TYPE (value);
-  int words = GET_MODE_BITSIZE (TYPE_MODE (type)) / 32;
+  int words = GET_MODE_BITSIZE (SCALAR_FLOAT_TYPE_MODE (type)) / 32;
 
   real_to_target (target_real, &TREE_REAL_CST (value),
  TYPE_MODE (type));
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index c649e54..6d7b839 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -2007,7 +2007,8 @@ fold_convert_const_real_from_fixed (tree type, const_tree 
arg1)
   REAL_VALUE_TYPE value;
   tree t;
 
-  real_convert_from_fixed (&value, TYPE_MODE (type), &TREE_FIXED_CST (arg1));
+  real_convert_from_fixed (&value, SCALAR_FLOAT_TYPE_MODE (type),
+  &TREE_FIXED_CST (arg1));
   t = build_real (type, value);
 
   TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
@@ -6970,7 +6971,7 @@ static int
 native_encode_real (const_tree expr, unsigned char *ptr, int len, int off)
 {
   tree type = TREE_TYPE (expr);
-  int total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
+  int total_bytes = GET_MODE_SIZE (SCALAR_FLOAT_TYPE_MODE (type));
   int byte, offset, word, words, bitpos;
   unsigned char value;
 
@@ -7215,7 +7216,7 @@ native_interpret_fixed (tree type, const unsigned char 
*ptr, int len)
 static tree
 native_interpret_real (tree type, const unsigned char *ptr, int len)
 {
-  machine_mode mode = TYPE_MODE (type);
+  scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (type);
   int total_bytes = GET_MODE_SIZE (mode);
   unsigned char value;
   /* There are always 32 bits in each long, no matter the size of
diff --git a/gcc/fortran/target-memory.c b/gcc/fortran/target-memory.c
index ac9cce2..b498f19 100644
--- a/gcc/fortran/target-memory.c
+++ b/gcc/fortran/target-memory.c
@@ -46,7 +46,7 @@ size_integer (int kind)
 static size_t
 size_float (int kind)
 {
-  return GET_MODE_SIZE (TYPE_MODE (gfc_get_real_type (kind)));;
+  return GET_MODE_SIZE (SCALAR_FLOAT_TYPE_MODE (gfc_get_real_type (kind)));
 }
 
 
diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c
index acd9164..5591b5f 100644
--- a/gcc/hsa-brig.c
+++ b/gcc/hsa-brig.c
@@ -909,7 +909,7 @@ emit_immediate_scalar_to_buffer (tree value, char *data, 
unsigned need_len)
 "operands");
  return 2;
}
-  unsigned int_len = GET_MODE_SIZE (TYPE_MODE (type));
+  unsigned int_len = GET_MODE_SIZE (SCALAR_FLOAT_TYPE_MODE (type));
   /* There are always 32 bits in each long, no matter the size of
 the hosts long.  */
   long tmp[6];
diff --git a/gcc/objc/objc-encoding.c b/gcc/objc/objc-encoding.c
index 4496a09..3b72dd

[10/67] Make assemble_real take a scalar_float_mode

2016-12-09 Thread Richard Sandiford
As per subject.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* output.h (assemble_real): Take a scalar_float_mode.
* config/arm/arm.c (arm_assemble_integer): Update accordingly.
* config/arm/arm.md (consttable_4): Likewise.
(consttable_8): Likewise.
(consttable_16): Likewise.
* config/mips/mips.md (consttable_float): Likewise.
* config/s390/s390.c (s390_output_pool_entry): Likewise.
* varasm.c (assemble_real): Take a scalar_float_mode.
(output_constant_pool_2): Update accordingly.
(output_constant): Likewise.

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index aeec412..6922c4e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -22397,8 +22397,9 @@ arm_assemble_integer (rtx x, unsigned int size, int 
aligned_p)
 for (i = 0; i < units; i++)
   {
 rtx elt = CONST_VECTOR_ELT (x, i);
-assemble_real
-  (*CONST_DOUBLE_REAL_VALUE (elt), GET_MODE_INNER (mode),
+   assemble_real
+ (*CONST_DOUBLE_REAL_VALUE (elt),
+  as_a  (GET_MODE_INNER (mode)),
   i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT);
   }
 
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index d561a4b..4a911a0 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -11226,13 +11226,11 @@
   {
 rtx x = operands[0];
 making_const_table = TRUE;
-switch (GET_MODE_CLASS (GET_MODE (x)))
+scalar_float_mode float_mode;
+if (is_a  (GET_MODE (x), &float_mode))
+  assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
+else
   {
-  case MODE_FLOAT:
-   assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
-  BITS_PER_WORD);
-   break;
-  default:
/* XXX: Sometimes gcc does something really dumb and ends up with
   a HIGH in a constant pool entry, usually because it's trying to
   load into a VFP register.  We know this will always be used in
@@ -11242,7 +11240,6 @@
  x = XEXP (x, 0);
 assemble_integer (x, 4, BITS_PER_WORD, 1);
mark_symbol_refs_as_used (x);
-break;
   }
 return \"\";
   }"
@@ -11256,16 +11253,12 @@
   "*
   {
 making_const_table = TRUE;
-switch (GET_MODE_CLASS (GET_MODE (operands[0])))
-  {
-  case MODE_FLOAT:
-   assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
-  GET_MODE (operands[0]), BITS_PER_WORD);
-   break;
-  default:
-assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
-break;
-  }
+scalar_float_mode float_mode;
+if (is_a  (GET_MODE (operands[0]), &float_mode))
+  assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
+float_mode, BITS_PER_WORD);
+else
+  assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
 return \"\";
   }"
   [(set_attr "length" "8")
@@ -11278,16 +11271,12 @@
   "*
   {
 making_const_table = TRUE;
-switch (GET_MODE_CLASS (GET_MODE (operands[0])))
-  {
-  case MODE_FLOAT:
-   assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
-  GET_MODE (operands[0]), BITS_PER_WORD);
-   break;
-  default:
-assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
-break;
-  }
+scalar_float_mode float_mode;
+if (is_a  (GET_MODE (operands[0]), &float_mode))
+  assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
+float_mode, BITS_PER_WORD);
+else
+  assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
 return \"\";
   }"
   [(set_attr "length" "16")
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index b2e5f97..73ca2fe 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -7371,7 +7371,7 @@
 {
   gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
   assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
-GET_MODE (operands[0]),
+as_a  (GET_MODE (operands[0])),
 GET_MODE_BITSIZE (GET_MODE (operands[0])));
   return "";
 }
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index a48663d..a3bb952 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9225,7 +9225,8 @@ s390_output_pool_entry (rtx exp, machine_mode mode, 
unsigned int align)
 case MODE_DECIMAL_FLOAT:
   gcc_assert (GET_CODE (exp) == CONST_DOUBLE);
 
-  assemble_real (*CONST_DOUBLE_REAL_VALUE (exp), mode, align);
+  assemble_real (*CONST_DOUBLE_REAL_VALUE (exp),
+as_a  (mode), align);
   break;
 
 case MODE_INT:
diff --git a/gcc/output.h b/gcc/output.h
index 6c99381..c94fe08 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -281,7 +281,7 @@ extern section *get_named_text_section (tree, const char *, 
const char *);
 /* Assemble the floating-point constant D into an objec

Re: [0/67] Add wrapper classes for machine_modes

2016-12-09 Thread Richard Biener
On Fri, Dec 9, 2016 at 1:48 PM, Richard Sandiford
 wrote:
> This series includes most of the changes in group C from:
>
> https://gcc.gnu.org/ml/gcc/2016-11/msg00033.html
>
> The idea is to add wrapper classes around machine_mode_enum
> for specific groups of modes, such as scalar integers, scalar floats,
> complex values, etc.  This has two main benefits: one specific to SVE
> and one not.
>
> The SVE-specific benefit is that it helps to introduce the concept
> of variable-length vectors.  To do that we need to change the size
> of a vector mode from being a known compile-time constant to being
> (possibly) a run-time invariant.  We then need to do the same for
> unconstrained machine_modes, which might or might not be vectors.
> Introducing these new constrained types means that we can continue
> to treat them as having a constant size.
>
> The other benefit is that it uses static type checking to enforce
> conditions that are easily forgotten otherwise.  The most common
> sources of problems seem to be:
>
> (a) using VOIDmode or BLKmode where a scalar integer was expected
> (e.g. when getting the number of bits in the value).
>
> (b) simplifying vector operations in ways that only make sense for
> scalars.
>
> The series helps with both of these, although we don't get the full
> benefit of (b) until variable-sized modes are introduced.
>
> I know of three specific cases in which the static type checking
> forced fixes for things that turned out to be real bugs (although
> we didn't know that at the time, otherwise we'd have posted patches).
> They were later fixed for trunk by:
>
>   https://gcc.gnu.org/ml/gcc-patches/2016-07/msg01783.html
>   https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02983.html
>   https://gcc.gnu.org/ml/gcc-patches/2016-11/msg02896.html
>
> The group C patches in ARM/sve-branch did slow compile time down a little.
> I've since taken steps to avoid that:
>
> - Make the tailcall pass handle aggregate parameters and return values
>   (already in trunk).
>
> - Turn some of the new wrapper functions into inline functions.
>
> - Make all the machmode.h macros that used:
>
> __builtin_constant_p (M) ? foo_inline (M) : foo_array[M[
>
>   forward to an ALWAYS_INLINE function, so that (a) M is only evaluated
>   once and (b) __builtin_constant_p is applied to a variable, and so is
>   deferred until later passes.  This helped the optimisation to fire in
>   more cases and to continue firing when M is a class rather than a
>   raw enum.
>
> - In a similar vein, make sure that conditions like:
>
>  SImode == DImode
>
>   are treated as builtin_constant_p by gencondmd, so that .md patterns
>   with those conditions are dropped.
>
> With these changes the series is actually a very slight compile-time win.
> That might seem unlikely, but there are several possible reasons:
>
> 1. The machmode.h macro change above might allow more constant folding.
>
> 2. The series has a tendency to evaluate modes once, rather than
>continually fetching them from (sometimes quite deep) rtx nests.
>Refetching a mode is a particular problem if call comes between
>two uses, since the compiler then has to re-evaluate the whole thing.
>
> 3. The series introduces many uses of new SCALAR_*TYPE_MODE macros,
>as alternatives to TYPE_MODE.  The new macros avoid the usual:
>
>  (VECTOR_TYPE_P (TYPE_CHECK (NODE)) \
>   ? vector_type_mode (NODE) : (NODE)->type_common.mode)
>
>and become direct field accesses in release builds.
>
>VECTOR_TYPE_P would be consistently false for these uses,
>but call-clobbered registers would usually be treated as clobbered
>by the condition as a whole.
>
> Maybe (3) is the most likely reason.
>
> I tested this by compiling the testsuite for:
>
> aarch64-linux-gnu alpha-linux-gnu arc-elf arm-linux-gnueabi
> arm-linux-gnueabihf avr-elf bfin-elf c6x-elf cr16-elf cris-elf
> epiphany-elf fr30-elf frv-linux-gnu ft32-elf h8300-elf
> hppa64-hp-hpux11.23 ia64-linux-gnu i686-pc-linux-gnu
> i686-apple-darwin iq2000-elf lm32-elf m32c-elf m32r-elf
> m68k-linux-gnu mcore-elf microblaze-elf mips-linux-gnu
> mipsisa64-linux-gnu mmix mn10300-elf moxie-rtems msp430-elf
> nds32le-elf nios2-linux-gnu nvptx-none pdp11 powerpc-linux-gnuspe
> powerpc-eabispe powerpc64-linux-gnu powerpc-ibm-aix7.0 rl78-elf
> rx-elf s390-linux-gnu s390x-linux-gnu sh-linux-gnu sparc-linux-gnu
> sparc64-linux-gnu sparc-wrs-vxworks spu-elf tilegx-elf tilepro-elf
> xstormy16-elf v850-elf vax-netbsdelf visium-elf x86_64-darwin
> x86_64-linux-gnu xtensa-elf
>
> and checking that there were no changes in assembly.  Also tested
> in the normal way on aarch64-linux-gnu and x86_64-linux-gnu.
>
> The series depends on the already-posted:
>
>   https://gcc.gnu.org/ml/gcc-patches/2016-11/msg01657.html
>
> Sorry that this is so late, been distracted by other things.  Even if
> we're too far into stage 3 for SVE itself to go in, I was hopi

Re: [PATCH] DWARF: make signedness explicit for enumerator const values

2016-12-09 Thread Mark Wielaard
On Fri, 2016-12-09 at 12:59 +0100, Pierre-Marie de Rodat wrote:
> There seems to be only two legal DWARF alternatives to solve this issue:
> one is to add a DW_AT_type attribute to DW_TAG_enumerator_type DIEs to
> make it point to a base type that specifies the signedness.  The other
> is to make sure the form of the DW_AT_const_value attribute carries the
> signedness information.

BTW. I think it should also be possible to simply attach a
DW_AT_encoding directly to the DW_TAG_enumeration_type. It seems a
simple oversight that option isn't listed in the current DWARF spec.

I filed an issue about it:
http://dwarfstd.org/ShowIssue.php?issue=161130.2
I haven't heard back from the committee. But Todd Allen from Concurrent
said their Ada compiler already does this when generating DWARF

Cheers,

Mark


[11/67] Add a float_mode_for_size helper function

2016-12-09 Thread Richard Sandiford
This provides a type-safe way to ask for a float mode and get it as a
scalar_float_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* coretypes.h (opt_scalar_float_mode): New typedef.
* machmode.h (float_mode_for_size): New function.
* emit-rtl.c (double_mode): Delete.
(init_emit_once): Use float_mode_for_size.
* stor-layout.c (layout_type): Likewise.

diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index f4c1859..8341cab 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -58,6 +58,7 @@ typedef const struct rtx_def *const_rtx;
 class machine_mode;
 class scalar_float_mode;
 template class opt_mode;
+typedef opt_mode opt_scalar_float_mode;
 
 /* Subclasses of rtx_def, using indentation to show the class
hierarchy, along with the relevant invariant.
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 3bcafbb..efddad4 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -71,7 +71,6 @@ struct target_rtl *this_target_rtl = &default_target_rtl;
 
 machine_mode byte_mode;/* Mode whose width is BITS_PER_UNIT.  */
 machine_mode word_mode;/* Mode whose width is BITS_PER_WORD.  */
-machine_mode double_mode;  /* Mode whose width is DOUBLE_TYPE_SIZE.  */
 machine_mode ptr_mode; /* Mode whose width is POINTER_SIZE.  */
 
 /* Datastructures maintained for currently processed function in RTL form.  */
@@ -5864,7 +5863,7 @@ init_emit_once (void)
 {
   int i;
   machine_mode mode;
-  machine_mode double_mode;
+  scalar_float_mode double_mode;
 
   /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE,
  CONST_FIXED, and memory attribute hash tables.  */
@@ -5908,7 +5907,7 @@ init_emit_once (void)
   else
 const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
 
-  double_mode = mode_for_size (DOUBLE_TYPE_SIZE, MODE_FLOAT, 0);
+  double_mode = *float_mode_for_size (DOUBLE_TYPE_SIZE);
 
   real_from_integer (&dconst0, double_mode, 0, SIGNED);
   real_from_integer (&dconst1, double_mode, 1, SIGNED);
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 996f991..41a3a00 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -513,7 +513,16 @@ extern const unsigned char mode_complex[NUM_MACHINE_MODES];
 
 extern machine_mode mode_for_size (unsigned int, enum mode_class, int);
 
-/* Similar, but find the smallest mode for a given width.  */
+/* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one
+   exists.  */
+
+inline opt_scalar_float_mode
+float_mode_for_size (unsigned int size)
+{
+  return dyn_cast  (mode_for_size (size, MODE_FLOAT, 0));
+}
+
+/* Similar to mode_for_size, but find the smallest mode for a given width.  */
 
 extern machine_mode smallest_mode_for_size (unsigned int,
 enum mode_class);
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 834cf8b..2cde94e 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -2132,14 +2132,16 @@ layout_type (tree type)
   break;
 
 case REAL_TYPE:
-  /* Allow the caller to choose the type mode, which is how decimal
-floats are distinguished from binary ones.  */
-  if (TYPE_MODE (type) == VOIDmode)
-   SET_TYPE_MODE (type,
-  mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0));
-  TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
-  TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
-  break;
+  {
+   /* Allow the caller to choose the type mode, which is how decimal
+  floats are distinguished from binary ones.  */
+   if (TYPE_MODE (type) == VOIDmode)
+ SET_TYPE_MODE (type, *float_mode_for_size (TYPE_PRECISION (type)));
+   scalar_float_mode mode = as_a  (TYPE_MODE (type));
+   TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
+   TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
+   break;
+  }
 
case FIXED_POINT_TYPE:
  /* TYPE_MODE (type) has been set already.  */



[12/67] Use opt_scalar_float_mode when iterating over float modes

2016-12-09 Thread Richard Sandiford
This means that we know when accessing the modes that the size is
a compile-time constant, even for SVE.  It also enables stricter
type safety in later patches.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* machmode.h (mode_iterator::start): Provide overload for opt_modes.
(mode_iterator::iterate_p): Likewise.
(mode_iterator::get_wider): Likewise.
* expr.c (init_expr_target): Use opt_scalar_float_mode.

gcc/ada/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* gcc-interface/misc.c (fp_prec_to_size): Use opt_scalar_float_mode.
(fp_size_to_prec): Likewise.

gcc/c-family/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* c-cppbuiltin.c (c_cpp_builtins): Use opt_scalar_float_mode.

gcc/fortran/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* trans-types.c (gfc_init_kinds): Use opt_scalar_float_mode
and FOR_EACH_MODE_IN_CLASS.

diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 4bb22ed..cef8d84 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -1278,11 +1278,11 @@ enumerate_modes (void (*f) (const char *, int, int, 
int, int, int, int, int))
 int
 fp_prec_to_size (int prec)
 {
-  machine_mode mode;
+  opt_scalar_float_mode mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
-if (GET_MODE_PRECISION (mode) == prec)
-  return GET_MODE_BITSIZE (mode);
+if (GET_MODE_PRECISION (*mode) == prec)
+  return GET_MODE_BITSIZE (*mode);
 
   gcc_unreachable ();
 }
@@ -1292,11 +1292,11 @@ fp_prec_to_size (int prec)
 int
 fp_size_to_prec (int size)
 {
-  machine_mode mode;
+  opt_scalar_float_mode mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
-if (GET_MODE_BITSIZE (mode) == size)
-  return GET_MODE_PRECISION (mode);
+if (GET_MODE_BITSIZE (*mode) == size)
+  return GET_MODE_PRECISION (*mode);
 
   gcc_unreachable ();
 }
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 0d6f538..32a999a 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1184,9 +1184,10 @@ c_cpp_builtins (cpp_reader *pfile)
   if (flag_building_libgcc)
 {
   /* Properties of floating-point modes for libgcc2.c.  */
-  machine_mode mode;
-  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
+  opt_scalar_float_mode mode_iter;
+  FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
{
+ scalar_float_mode mode = *mode_iter;
  const char *name = GET_MODE_NAME (mode);
  char *macro_name
= (char *) alloca (strlen (name)
diff --git a/gcc/expr.c b/gcc/expr.c
index a3a3e86..d277a88 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -110,7 +110,6 @@ void
 init_expr_target (void)
 {
   rtx pat;
-  machine_mode mode;
   int num_clobbers;
   rtx mem, mem1;
   rtx reg;
@@ -129,7 +128,7 @@ init_expr_target (void)
   pat = gen_rtx_SET (NULL_RTX, NULL_RTX);
   PATTERN (insn) = pat;
 
-  for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
+  for (machine_mode mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
mode = (machine_mode_enum) ((int) mode + 1))
 {
   int regno;
@@ -175,9 +174,11 @@ init_expr_target (void)
 
   mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
 
-  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
+  opt_scalar_float_mode mode_iter;
+  FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
 {
-  machine_mode srcmode;
+  scalar_float_mode mode = *mode_iter;
+  scalar_float_mode srcmode;
   FOR_EACH_MODE_UNTIL (srcmode, mode)
{
  enum insn_code ic;
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index c0d1a17..4c69237 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -348,6 +348,7 @@ void
 gfc_init_kinds (void)
 {
   machine_mode_enum mode;
+  opt_scalar_float_mode float_mode_iter;
   int i_index, r_index, kind;
   bool saw_i4 = false, saw_i8 = false;
   bool saw_r4 = false, saw_r8 = false, saw_r10 = false, saw_r16 = false;
@@ -403,9 +404,10 @@ gfc_init_kinds (void)
   /* Set the maximum integer kind.  Used with at least BOZ constants.  */
   gfc_max_integer_kind = gfc_integer_kinds[i_index - 1].kind;
 
-  for (r_index = 0, mode = MIN_MODE_FLOAT; mode <= MAX_MODE_FLOAT;
-   mode = (machine_mode_enum) ((int) mode + 1))
+  r_index = 0;
+  FOR_EACH_MODE_IN_CLASS (float_mode_iter, MODE_FLOAT)
 {
+  scalar_float_mode mode = *float_mode_iter;
   const struct real_format *fmt = REAL_MODE_FORMAT (mode);
   int kind;
 
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 41a3a00..2f4b076 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -628,6 +628,16 @@ namespace mode_iterator
 {
   /* Start mode iterator *ITER at the first mode in class MCLASS, if any.  */
 
+  template
+  inline void
+  start (opt_mode

[13/67] Make floatn_mode return an opt_scalar_float_mode

2016-12-09 Thread Richard Sandiford
As per subject.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* target.def (default_floatn_mode): Return an opt_scalar_float_mode.
* doc/tm.texi: Regenerate.
* config/arm/arm.c (arm_floatn_mode): Return an opt_scalar_float_mode.
* config/rs6000/rs6000.c (rs6000_floatn_mode): Likewise.
* targhooks.h (default_floatn_mode): Likewise.
* targhooks.c (default_floatn_mode): Likewise.
* tree.c (build_common_tree_nodes): Update accordingly.

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6922c4e..45c08bf 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -303,7 +303,7 @@ static bool arm_asm_elf_flags_numeric (unsigned int flags, 
unsigned int *num);
 static unsigned int arm_elf_section_type_flags (tree decl, const char *name,
int reloc);
 static void arm_expand_divmod_libfunc (rtx, machine_mode, rtx, rtx, rtx *, rtx 
*);
-static machine_mode arm_floatn_mode (int, bool);
+static opt_scalar_float_mode arm_floatn_mode (int, bool);
 
 /* Table of machine attributes.  */
 static const struct attribute_spec arm_attribute_table[] =
@@ -23372,11 +23372,15 @@ arm_excess_precision (enum excess_precision_type type)
 /* Implement TARGET_FLOATN_MODE.  Make very sure that we don't provide
_Float16 if we are using anything other than ieee format for 16-bit
floating point.  Otherwise, punt to the default implementation.  */
-static machine_mode
+static opt_scalar_float_mode
 arm_floatn_mode (int n, bool extended)
 {
   if (!extended && n == 16)
-return arm_fp16_format == ARM_FP16_FORMAT_IEEE ? HFmode : VOIDmode;
+{
+  if (arm_fp16_format == ARM_FP16_FORMAT_IEEE)
+   return HFmode;
+  return opt_scalar_float_mode ();
+}
 
   return default_floatn_mode (n, extended);
 }
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e868cef..08a069d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -37693,7 +37693,7 @@ rs6000_vector_mode_supported_p (machine_mode mode)
 }
 
 /* Target hook for floatn_mode.  */
-static machine_mode
+static opt_scalar_float_mode
 rs6000_floatn_mode (int n, bool extended)
 {
   if (extended)
@@ -37707,10 +37707,10 @@ rs6000_floatn_mode (int n, bool extended)
  if (TARGET_FLOAT128_KEYWORD)
return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode;
  else
-   return VOIDmode;
+   return opt_scalar_float_mode ();
 
case 128:
- return VOIDmode;
+ return opt_scalar_float_mode ();
 
default:
  /* Those are the only valid _FloatNx types.  */
@@ -37731,10 +37731,10 @@ rs6000_floatn_mode (int n, bool extended)
  if (TARGET_FLOAT128_KEYWORD)
return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode;
  else
-   return VOIDmode;
+   return opt_scalar_float_mode ();
 
default:
- return VOIDmode;
+ return opt_scalar_float_mode ();
}
 }
 
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 199ec75..187d20d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4258,22 +4258,22 @@ hook returns true for all of @code{SFmode}, 
@code{DFmode},
 @code{XFmode} and @code{TFmode}, if such modes exist.
 @end deftypefn
 
-@deftypefn {Target Hook} machine_mode TARGET_FLOATN_MODE (int @var{n}, bool 
@var{extended})
+@deftypefn {Target Hook} opt_scalar_float_mode TARGET_FLOATN_MODE (int 
@var{n}, bool @var{extended})
 Define this to return the machine mode to use for the type 
 @code{_Float@var{n}}, if @var{extended} is false, or the type 
-@code{_Float@var{n}x}, if @var{extended} is true.  If such a type 
-is not supported, return @code{VOIDmode}.  The default version of this 
-hook returns @code{SFmode} for @code{_Float32}, @code{DFmode} for 
+@code{_Float@var{n}x}, if @var{extended} is true.  If such a type is not
+supported, return @code{opt_scalar_float_mode ()}.  The default version of
+this hook returns @code{SFmode} for @code{_Float32}, @code{DFmode} for
 @code{_Float64} and @code{_Float32x} and @code{TFmode} for 
 @code{_Float128}, if those modes exist and satisfy the requirements for 
 those types and pass @code{TARGET_SCALAR_MODE_SUPPORTED_P} and 
 @code{TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P}; for @code{_Float64x}, it 
 returns the first of @code{XFmode} and @code{TFmode} that exists and 
 satisfies the same requirements; for other types, it returns 
-@code{VOIDmode}.  The hook is only called for values of @var{n} and 
-@var{extended} that are valid according to ISO/IEC TS 18661-3:2015; that 
-is, @var{n} is one of 32, 64, 128, or, if @var{extended} is false, 16 or 
-greater than 128 and a multiple of 32.
+@code{opt_scalar_float_mode ()}.  The hook is only called for values
+of @var{n} and @var{extended} that are valid according to
+ISO/IEC TS 18661-3:2015; that is, @var{n} is one of 32, 64, 128, or,
+if @var{extended} i

[14/67] Make libgcc_floating_mode_supported_p take a scalar_float_mode

2016-12-09 Thread Richard Sandiford
As per subject.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* target.def (default_libgcc_floating_mode_supported_p): Take
a scalar_float_mode.
* doc/tm.texi: Regenerate.
* targhooks.h (default_floatn_mode): Take a scalar_float_mode.
* targhooks.c (default_floatn_mode): Likewise.
* config/aarch64/aarch64.c (aarch64_libgcc_floating_mode_supported_p):
Likewise.

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index cc97b7a..f399514 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -14547,7 +14547,7 @@ aarch64_optab_supported_p (int op, machine_mode mode1, 
machine_mode,
if MODE is HFmode, and punt to the generic implementation otherwise.  */
 
 static bool
-aarch64_libgcc_floating_mode_supported_p (machine_mode mode)
+aarch64_libgcc_floating_mode_supported_p (scalar_float_mode mode)
 {
   return (mode == HFmode
  ? true
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 187d20d..4993817 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4250,7 +4250,7 @@ If this hook allows @code{val} to have a scalar mode, then
 @code{int8x8x3_t}s in registers rather than forcing them onto the stack.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P 
(machine_mode @var{mode})
+@deftypefn {Target Hook} bool TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P 
(scalar_float_mode @var{mode})
 Define this to return nonzero if libgcc provides support for the 
 floating-point mode @var{mode}, which is known to pass 
 @code{TARGET_SCALAR_MODE_SUPPORTED_P}.  The default version of this 
diff --git a/gcc/target.def b/gcc/target.def
index 09b23b2..fa765de 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -3358,7 +3358,7 @@ floating-point mode @var{mode}, which is known to pass \n\
 @code{TARGET_SCALAR_MODE_SUPPORTED_P}.  The default version of this \n\
 hook returns true for all of @code{SFmode}, @code{DFmode}, \n\
 @code{XFmode} and @code{TFmode}, if such modes exist.",
- bool, (machine_mode mode),
+ bool, (scalar_float_mode mode),
  default_libgcc_floating_mode_supported_p)
 
 DEFHOOK
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index f8a9fae..90892fa 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -441,7 +441,7 @@ default_scalar_mode_supported_p (machine_mode mode)
be supported as a scalar mode).  */
 
 bool
-default_libgcc_floating_mode_supported_p (machine_mode mode)
+default_libgcc_floating_mode_supported_p (scalar_float_mode mode)
 {
   switch (mode)
 {
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 7b633c2..1a56ec7 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -72,7 +72,7 @@ extern bool default_print_operand_punct_valid_p (unsigned 
char);
 extern tree default_mangle_assembler_name (const char *);
 
 extern bool default_scalar_mode_supported_p (machine_mode);
-extern bool default_libgcc_floating_mode_supported_p (machine_mode);
+extern bool default_libgcc_floating_mode_supported_p (scalar_float_mode);
 extern opt_scalar_float_mode default_floatn_mode (int, bool);
 extern bool targhook_words_big_endian (void);
 extern bool targhook_float_words_big_endian (void);



[15/67] Add scalar_int_mode

2016-12-09 Thread Richard Sandiford
Similar to the previous scalar_float_mode patch, but for modes that
satisfy SCALAR_INT_MODE_P.  There are very many uses of scalar integers,
so this patch only makes one token change to the types of byte_mode,
word_mode and ptr_mode.  The next patches in the series gradually
replace more uses.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* config/epiphany/epiphany.h (RTX_OK_FOR_OFFSET_P): Add casts
to machine_mode.
* coretypes.h (scalar_int_mode): New type.
(opt_scalar_int_mode): New typedef.
* machmode.h (scalar_int_mode): New class.
(scalar_int_mode::includes_p): New function.
(scalar_int_mode::from_int): New function.
(byte_mode): Change type to scalar_int_mode.
(word_mode): Likewise.
(ptr_mode): Likewise.
* emit-rtl.c (byte_mode): Likewise.
(word_mode): Likewise.
(ptr_mode): Likewise.
(init_derived_machine_modes): Update accordingly.
* genmodes.c (get_mode_class): Return scalar_int_mode for MODE_INT
and MODE_PARTIAL_INT.

diff --git a/gcc/config/epiphany/epiphany.h b/gcc/config/epiphany/epiphany.h
index 9e7ee50..3818af3 100644
--- a/gcc/config/epiphany/epiphany.h
+++ b/gcc/config/epiphany/epiphany.h
@@ -641,7 +641,8 @@ typedef struct GTY (()) machine_function
 
 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
   RTX_OK_FOR_OFFSET_1 (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \
-  && epiphany_vect_align == 4 ? SImode : (MODE), X)
+  && epiphany_vect_align == 4 \
+  ? (machine_mode) SImode : (machine_mode) (MODE), X)
 #define RTX_OK_FOR_OFFSET_1(MODE, X) \
   (GET_CODE (X) == CONST_INT \
&& !(INTVAL (X) & (GET_MODE_SIZE (MODE) - 1)) \
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 8341cab..6dc3e88 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -56,8 +56,10 @@ struct rtx_def;
 typedef struct rtx_def *rtx;
 typedef const struct rtx_def *const_rtx;
 class machine_mode;
+class scalar_int_mode;
 class scalar_float_mode;
 template class opt_mode;
+typedef opt_mode opt_scalar_int_mode;
 typedef opt_mode opt_scalar_float_mode;
 
 /* Subclasses of rtx_def, using indentation to show the class
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index efddad4..b9d87d3 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -69,9 +69,9 @@ struct target_rtl *this_target_rtl = &default_target_rtl;
 
 /* Commonly used modes.  */
 
-machine_mode byte_mode;/* Mode whose width is BITS_PER_UNIT.  */
-machine_mode word_mode;/* Mode whose width is BITS_PER_WORD.  */
-machine_mode ptr_mode; /* Mode whose width is POINTER_SIZE.  */
+scalar_int_mode byte_mode; /* Mode whose width is BITS_PER_UNIT.  */
+scalar_int_mode word_mode; /* Mode whose width is BITS_PER_WORD.  */
+scalar_int_mode ptr_mode;  /* Mode whose width is POINTER_SIZE.  */
 
 /* Datastructures maintained for currently processed function in RTL form.  */
 
@@ -5838,22 +5838,24 @@ init_emit_regs (void)
 void
 init_derived_machine_modes (void)
 {
-  byte_mode = VOIDmode;
-  word_mode = VOIDmode;
-
-  machine_mode mode;
-  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
+  opt_scalar_int_mode mode_iter, opt_byte_mode, opt_word_mode;
+  FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
 {
+  scalar_int_mode mode = *mode_iter;
+
   if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
- && byte_mode == VOIDmode)
-   byte_mode = mode;
+ && !opt_byte_mode.exists ())
+   opt_byte_mode = mode;
 
   if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD
- && word_mode == VOIDmode)
-   word_mode = mode;
+ && !opt_word_mode.exists ())
+   opt_word_mode = mode;
 }
 
-  ptr_mode = mode_for_size (POINTER_SIZE, GET_MODE_CLASS (Pmode), 0);
+  byte_mode = *opt_byte_mode;
+  word_mode = *opt_word_mode;
+  ptr_mode = as_a  (mode_for_size (POINTER_SIZE,
+   MODE_INT, 0));
 }
 
 /* Create some permanent unique rtl objects shared between all functions.  */
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index 3cc426e..eddbff7 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -1137,6 +1137,10 @@ get_mode_class (struct mode_data *mode)
 {
   switch (mode->cl)
 {
+case MODE_INT:
+case MODE_PARTIAL_INT:
+  return "scalar_int_mode";
+
 case MODE_FLOAT:
 case MODE_DECIMAL_FLOAT:
   return "scalar_float_mode";
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 2f4b076..8c8dd54 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -292,6 +292,40 @@ is_a (machine_mode_enum m, U *result)
   return false;
 }
 
+/* Represents a machine mode that is known to be a SCALAR_INT_MODE_P.  */
+class scalar_int_mode
+{
+public:
+  ALWAYS_INLINE scalar_int_mode () {}
+  ALWAYS_INLINE operator machine_mode_enum () const { return m_mode; }
+
+  static bool includes_p (machine_mode_enum);
+  static scalar_int_mode from_int (int);
+
+PROTECT_ENUM_CON

[16/67] Add scalar_int_mode_pod

2016-12-09 Thread Richard Sandiford
This patch adds a POD class for scalar integers, as an instance
of a new pod_mode template.  Later patches will use pod_mode in
situations that really do need to be POD; in this patch we're
simply using PODs to remove load-time initialisation.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* coretypes.h (pod_mode): New type.
(scalar_int_mode_pod): New typedef.
* machmode.h (pod_mode): New class.
(int_n_data_t::m): Change type to scalar_int_mode_pod.
* genmodes.c (emit_mode_int_n): Update accordingly.

diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 6dc3e88..5073f35 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -61,6 +61,8 @@ class scalar_float_mode;
 template class opt_mode;
 typedef opt_mode opt_scalar_int_mode;
 typedef opt_mode opt_scalar_float_mode;
+template class pod_mode;
+typedef pod_mode scalar_int_mode_pod;
 
 /* Subclasses of rtx_def, using indentation to show the class
hierarchy, along with the relevant invariant.
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index eddbff7..8ee0fae6 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -1799,7 +1799,7 @@ emit_mode_int_n (void)
   m = mode_sort[i];
   printf(" {\n");
   tagged_printf ("%u", m->int_n, m->name);
-  printf ("E_%smode,", m->name);
+  printf ("{ E_%smode },", m->name);
   printf(" },\n");
 }
 
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 8c8dd54..bf568c9 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -247,6 +247,17 @@ opt_mode::exists (U *mode) const
   return false;
 }
 
+/* A POD version of mode class T.  */
+
+template
+struct pod_mode
+{
+  machine_mode_enum m_mode;
+  ALWAYS_INLINE operator machine_mode_enum () const { return m_mode; }
+  ALWAYS_INLINE operator T () const { return T::from_int (m_mode); }
+  ALWAYS_INLINE pod_mode &operator = (const T &m) { m_mode = m; return *this; }
+};
+
 /* Return true if mode M has type T.  */
 
 template
@@ -649,7 +660,7 @@ extern void init_adjust_machine_modes (void);
 struct int_n_data_t {
   /* These parts are initailized by genmodes output */
   unsigned int bitsize;
-  machine_mode_enum m;
+  scalar_int_mode_pod m;
   /* RID_* is RID_INTN_BASE + index into this array */
 };
 



[17/67] Add an int_mode_for_size helper function

2016-12-09 Thread Richard Sandiford
This patch adds a wrapper around mode_for_size for cases in which
the mode class is MODE_INT (the commonest case).  The return type
can then be an opt_scalar_int_mode instead of a machine_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* machmode.h (int_mode_for_size): New function.
* builtins.c (set_builtin_user_assembler_name): Use int_mode_for_size
instead of mode_for_size.
* calls.c (save_fixed_argument_area): Likewise.  Make use of BLKmode
explicit.
* combine.c (expand_field_assignment): Use int_mode_for_size
instead of mode_for_size.
(make_extraction): Likewise.
(simplify_shift_const_1): Likewise.
(simplify_comparison): Likewise.
* dojump.c (do_jump): Likewise.
* dwarf2out.c (mem_loc_descriptor): Likewise.
* emit-rtl.c (init_derived_machine_modes): Likewise.
* expmed.c (flip_storage_order): Likewise.
(convert_extracted_bit_field): Likewise.
* expr.c (copy_blkmode_from_reg): Likewise.
* graphite-isl-ast-to-gimple.c (max_mode_int_precision): Likewise.
* internal-fn.c (expand_mul_overflow): Likewise.
* lower-subreg.c (simple_move): Likewise.
* optabs-libfuncs.c (init_optabs): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
* stor-layout.c (vector_type_mode): Likewise.
* tree-ssa-strlen.c (handle_builtin_memcmp): Likewise.
* tree-vect-data-refs.c (vect_lanes_optab_supported_p): Likewise.
* tree-vect-generic.c (expand_vector_parallel): Likewise.
* tree-vect-stmts.c (vectorizable_load): Likewise.

gcc/ada/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* gcc-interface/decl.c (gnat_to_gnu_entity): Use int_mode_for_size
instead of mode_for_size.
(gnat_to_gnu_subprog_type): Likewise.
* gcc-interface/utils.c (make_type_from_size): Likewise.

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index d3bee34..843024e 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -3859,11 +3859,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree 
gnu_expr, bool definition)
/* True if we make a dummy type here.  */
bool made_dummy = false;
/* The mode to be used for the pointer type.  */
-   machine_mode p_mode = mode_for_size (esize, MODE_INT, 0);
+   scalar_int_mode p_mode;
/* The GCC type used for the designated type.  */
tree gnu_desig_type = NULL_TREE;
 
-   if (!targetm.valid_pointer_mode (p_mode))
+   if (!int_mode_for_size (esize, 0).exists (&p_mode)
+   || !targetm.valid_pointer_mode (p_mode))
  p_mode = ptr_mode;
 
/* If either the designated type or its full view is an unconstrained
@@ -6113,12 +6114,11 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool 
definition,
  unsigned int size
= TREE_INT_CST_LOW (TYPE_SIZE (gnu_cico_return_type));
  unsigned int i = BITS_PER_UNIT;
- machine_mode mode;
+ scalar_int_mode mode;
 
  while (i < size)
i <<= 1;
- mode = mode_for_size (i, MODE_INT, 0);
- if (mode != BLKmode)
+ if (int_mode_for_size (i, 0).exists (&mode))
{
  SET_TYPE_MODE (gnu_cico_return_type, mode);
  SET_TYPE_ALIGN (gnu_cico_return_type,
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 29e5203..937691c 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -1151,8 +1151,9 @@ make_type_from_size (tree type, tree size_tree, bool 
for_biased)
 may need to return the thin pointer.  */
   if (TYPE_FAT_POINTER_P (type) && size < POINTER_SIZE * 2)
{
- machine_mode p_mode = mode_for_size (size, MODE_INT, 0);
- if (!targetm.valid_pointer_mode (p_mode))
+ scalar_int_mode p_mode;
+ if (!int_mode_for_size (size, 0).exists (&p_mode)
+ || !targetm.valid_pointer_mode (p_mode))
p_mode = ptr_mode;
  return
build_pointer_type_for_mode
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6de9a33..655ae27 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -10250,9 +10250,9 @@ set_builtin_user_assembler_name (tree decl, const char 
*asmspec)
   if (DECL_FUNCTION_CODE (decl) == BUILT_IN_FFS
   && INT_TYPE_SIZE < BITS_PER_WORD)
 {
+  scalar_int_mode mode = *int_mode_for_size (INT_TYPE_SIZE, 0);
   set_user_assembler_libfunc ("ffs", asmspec);
-  set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
-"ffs");
+  set_optab_libfunc (ffs_optab, mode, "ffs");
 }
 }
 
diff --git a/gcc/calls.c b/gcc/calls.c
index fcfee25..7e58e14 100644
--- a/gcc/calls.c
+++ b/gcc/

[18/67] Make int_mode_for_mode return an opt_scalar_int_mode

2016-12-09 Thread Richard Sandiford
Also use int_mode_for_mode instead of (int_)mode_for_size
in cases where the requested size was the bitsize of an
existing mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* machmode.h (opt_mode::else_blk): New function.
(int_mode_for_mode): Declare.
* stor-layout.c (int_mode_for_mode): Return an opt_scalar_int_mode.
* builtins.c (expand_builtin_signbit): Adjust for new int_mode_for_mode
return type.
* cfgexpand.c (expand_debug_expr): Likewise.
* combine.c (gen_lowpart_or_truncate): Likewise.
(gen_lowpart_for_combine): Likewise.
* config/aarch64/aarch64.c (aarch64_emit_approx_sqrt): Likewise.
* config/avr/avr.c (avr_to_int_mode): Likewise.
(avr_out_plus_1): Likewise.
(avr_out_plus): Likewise.
(avr_out_round): Likewise.
* config/i386/i386.c (ix86_split_to_parts): Likewise.
* config/spu/spu.c (spu_split_immediate): Likewise.
(spu_expand_mov): Likewise.
* dse.c (get_stored_val): Likewise.
* expmed.c (store_bit_field_1): Likewise.
(convert_extracted_bit_field): Use int_mode_for_mode instead of
int_mode_for_size.
(extract_bit_field_1): Adjust for new int_mode_for_mode return type.
(extract_low_bits): Likewise.
* expr.c (emit_group_load_1): Likewise.  Separate out the BLKmode
handling rather than repeating the check.
(emit_group_store): Likewise.
(emit_move_via_integer): Adjust for new int_mode_for_mode return type.
* optabs.c (expand_absneg_bit): Likewise.
(expand_copysign_absneg): Likewise.
(expand_copysign_bit): Likewise.
* tree-if-conv.c (ifcvt_can_use_mask_load_store): Likewise.
* tree-vect-slp.c (vect_transform_slp_perm_load): Likewise.
* tree-vect-stmts.c (vect_gen_perm_mask_any): Likewise.
* var-tracking.c (prepare_call_arguments):  Likewise.
* config/rs6000/rs6000.c (rs6000_do_expand_vec_perm): Use
int_mode_for_mode instead of mode_for_size.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 655ae27..00a0a73 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5258,8 +5258,7 @@ expand_builtin_signbit (tree exp, rtx target)
 
   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
 {
-  imode = int_mode_for_mode (fmode);
-  gcc_assert (imode != BLKmode);
+  imode = *int_mode_for_mode (fmode);
   temp = gen_lowpart (imode, temp);
 }
   else
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 97dc648..3915c97 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4827,10 +4827,11 @@ expand_debug_expr (tree exp)
}
  else
{
- machine_mode ifmode = int_mode_for_mode (mode);
- machine_mode ihmode = int_mode_for_mode (imode);
+ scalar_int_mode ifmode;
+ scalar_int_mode ihmode;
  rtx halfsize;
- if (ifmode == BLKmode || ihmode == BLKmode)
+ if (!int_mode_for_mode (mode).exists (&ifmode)
+ || !int_mode_for_mode (imode).exists (&ihmode))
return NULL;
  halfsize = GEN_INT (GET_MODE_BITSIZE (ihmode));
  re = op0;
diff --git a/gcc/combine.c b/gcc/combine.c
index ed4f755..573c558 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -8416,8 +8416,8 @@ gen_lowpart_or_truncate (machine_mode mode, rtx x)
 {
   /* Bit-cast X into an integer mode.  */
   if (!SCALAR_INT_MODE_P (GET_MODE (x)))
-   x = gen_lowpart (int_mode_for_mode (GET_MODE (x)), x);
-  x = simplify_gen_unary (TRUNCATE, int_mode_for_mode (mode),
+   x = gen_lowpart (*int_mode_for_mode (GET_MODE (x)), x);
+  x = simplify_gen_unary (TRUNCATE, *int_mode_for_mode (mode),
  x, GET_MODE (x));
 }
 
@@ -11459,7 +11459,7 @@ gen_lowpart_for_combine (machine_mode omode, rtx x)
 
   if (imode == VOIDmode)
{
- imode = int_mode_for_mode (omode);
+ imode = *int_mode_for_mode (omode);
  x = gen_lowpart_common (imode, x);
  if (x == NULL)
goto fail;
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index f399514..fc2bcad 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7867,7 +7867,7 @@ aarch64_emit_approx_sqrt (rtx dst, rtx src, bool recp)
 return false;
 
   machine_mode mmsk = mode_for_vector
-   (int_mode_for_mode (GET_MODE_INNER (mode)),
+   (*int_mode_for_mode (GET_MODE_INNER (mode)),
 GET_MODE_NUNITS (mode));
   bool use_approx_sqrt_p = (!recp
&& (flag_mlow_precision_sqrt
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 732e030..e3a611f 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -279,7 +279,7 @@ avr_to_int_mode (rtx x)
 
   return VOIDmode == mode
 ? x
-

[19/67] Add a smallest_int_mode_for_size helper function

2016-12-09 Thread Richard Sandiford
This patch adds a wrapper around smallest_mode_for_size
for cases in which the mode class is MODE_INT.  Unlike
(int_)mode_for_size, smallest_mode_for_size always returns
a mode of the specified class, asserting if no such mode exists.
smallest_int_mode_for_size therefore returns a scalar_int_mode
rather than an opt_scalar_int_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* machmode.h (smallest_mode_for_size): Fix formatting.
(smallest_int_mode_for_size): New function.
* cfgexpand.c (expand_debug_expr): Use smallest_int_mode_for_size
instead of smallest_mopde_for_size.
* combine.c (make_extraction): Likewise.
* config/arc/arc.c (arc_expand_movmem): Likewise.
* config/i386/i386.c (ix86_get_mask_mode): Likewise.
* config/i386/i386.md (define_split): Likewise.
* config/s390/s390.c (s390_expand_insv): Likewise.
* config/sparc/sparc.c (assign_int_registers): Likewise.
* config/spu/spu.c (spu_function_value): Likewise.
(spu_function_arg): Likewise.
* coverage.c (get_gcov_type): Likewise.
(get_gcov_unsigned_t): Likewise.
* dse.c (find_shift_sequence): Likewise.
* expr.c (convert_move): Likewise.
(store_field): Likewise.
* internal-fn.c (expand_arith_overflow): Likewise.
* optabs-query.c (get_best_extraction_insn): Likewise.
* optabs.c (expand_twoval_binop_libfunc): Likewise.
* stor-layout.c (layout_type): Likewise.
(initialize_sizetypes): Likewise.
* targhooks.c (default_get_mask_mode): Likewise.
* tree-ssa-loop-manip.c (canonicalize_loop_ivs): Likewise.

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3915c97..b531996 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4486,7 +4486,7 @@ expand_debug_expr (tree exp)
  {
if (mode1 == VOIDmode)
  /* Bitfield.  */
- mode1 = smallest_mode_for_size (bitsize, MODE_INT);
+ mode1 = smallest_int_mode_for_size (bitsize);
if (bitpos >= BITS_PER_UNIT)
  {
op0 = adjust_address_nv (op0, mode1, bitpos / BITS_PER_UNIT);
diff --git a/gcc/combine.c b/gcc/combine.c
index 573c558..29b849a 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7586,7 +7586,7 @@ make_extraction (machine_mode mode, rtx inner, 
HOST_WIDE_INT pos,
 {
   /* Be careful not to go beyond the extracted object and maintain the
 natural alignment of the memory.  */
-  wanted_inner_mode = smallest_mode_for_size (len, MODE_INT);
+  wanted_inner_mode = smallest_int_mode_for_size (len);
   while (pos % GET_MODE_BITSIZE (wanted_inner_mode) + len
 > GET_MODE_BITSIZE (wanted_inner_mode))
wanted_inner_mode = *GET_MODE_WIDER_MODE (wanted_inner_mode);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 2b25a37..bc5c031 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -7621,7 +7621,7 @@ arc_expand_movmem (rtx *operands)
 
   while (piece > size)
piece >>= 1;
-  mode = smallest_mode_for_size (piece * BITS_PER_UNIT, MODE_INT);
+  mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT);
   /* If we don't re-use temporaries, the scheduler gets carried away,
 and the register pressure gets unnecessarily high.  */
   if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0fbb3ed..4d74bc4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -50331,11 +50331,11 @@ ix86_get_mask_mode (unsigned nunits, unsigned 
vector_size)
   || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16)))
 {
   if (elem_size == 4 || elem_size == 8 || TARGET_AVX512BW)
-   return smallest_mode_for_size (nunits, MODE_INT);
+   return smallest_int_mode_for_size (nunits);
 }
 
-  machine_mode elem_mode
-= smallest_mode_for_size (elem_size * BITS_PER_UNIT, MODE_INT);
+  scalar_int_mode elem_mode
+= smallest_int_mode_for_size (elem_size * BITS_PER_UNIT);
 
   gcc_assert (elem_size * nunits == vector_size);
 
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f2248a5..1433cbf 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -7936,7 +7936,7 @@
 no matter the size of the test.  So find a mode that works.  */
   if (! MEM_VOLATILE_P (val))
{
- mode = smallest_mode_for_size (pos + len, MODE_INT);
+ mode = smallest_int_mode_for_size (pos + len);
  val = adjust_address (val, mode, 0);
}
 }
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index a3bb952..510c24c 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -6093,7 +6093,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
   return true;
 }
 
-  smode = smallest_mode_for_size (bitsize, MODE_INT);
+  smode = smalle

[20/67] Replace MODE_INT checks with is_int_mode

2016-12-09 Thread Richard Sandiford
Replace checks of "GET_MODE_CLASS (...) == MODE_INT" with
"is_int_mode (..., &var)", in cases where it becomes useful
to refer to the mode as a scalar_int_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* machmode.h (is_int_mode): New fuction.
* combine.c (find_split_point): Use it.
(combine_simplify_rtx): Likewise.
(simplify_if_then_else): Likewise.
(simplify_set): Likewise.
(simplify_shift_const_1): Likewise.
(simplify_comparison): Likewise.
* config/aarch64/aarch64.c (aarch64_rtx_costs): Likewise.
* cse.c (notreg_cost): Likewise.
(cse_insn): Likewise.
* cselib.c (cselib_lookup_1): Likewise.
* dojump.c (do_jump_1): Likewise.
(do_compare_rtx_and_jump): Likewise.
* dse.c (get_call_args): Likewise.
* dwarf2out.c (rtl_for_decl_init): Likewise.
(native_encode_initializer): Likewise.
* expmed.c (emit_store_flag_1): Likewise.
(emit_store_flag): Likewise.
* expr.c (convert_modes): Likewise.
(store_field): Likewise.
(expand_expr_real_1): Likewise.
* fold-const.c (fold_read_from_constant_string): Likewise.
* optabs-libfuncs.c (gen_int_libfunc): Likewise.
* optabs.c (expand_binop): Likewise.
(expand_unop): Likewise.
(expand_abs_nojump): Likewise.
(expand_one_cmpl_abs_nojump): Likewise.
* simplify-rtx.c (mode_signbit_p): Likewise.
(val_signbit_p): Likewise.
(val_signbit_known_set_p): Likewise.
(val_signbit_known_clear_p): Likewise.
(simplify_relational_operation_1): Likewise.
* stor-layout.c (vector_type_mode): Likewise.

diff --git a/gcc/combine.c b/gcc/combine.c
index 29b849a..5168488 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -4766,6 +4766,7 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
   HOST_WIDE_INT pos = 0;
   int unsignedp = 0;
   rtx inner = NULL_RTX;
+  scalar_int_mode inner_mode;
 
   /* First special-case some codes.  */
   switch (code)
@@ -5007,12 +5008,12 @@ find_split_point (rtx *loc, rtx_insn *insn, bool 
set_src)
  /* We can't optimize if either mode is a partial integer
 mode as we don't know how many bits are significant
 in those modes.  */
- if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_PARTIAL_INT
+ if (!is_int_mode (GET_MODE (inner), &inner_mode)
  || GET_MODE_CLASS (GET_MODE (SET_SRC (x))) == MODE_PARTIAL_INT)
break;
 
  pos = 0;
- len = GET_MODE_PRECISION (GET_MODE (inner));
+ len = GET_MODE_PRECISION (inner_mode);
  unsignedp = 0;
  break;
 
@@ -5535,6 +5536,7 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int 
in_dest,
 {
   enum rtx_code code = GET_CODE (x);
   machine_mode mode = GET_MODE (x);
+  scalar_int_mode int_mode;
   rtx temp;
   int i;
 
@@ -6045,47 +6047,51 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int 
in_dest,
;
 
  else if (STORE_FLAG_VALUE == 1
- && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
- && op1 == const0_rtx
- && mode == GET_MODE (op0)
- && nonzero_bits (op0, mode) == 1)
-   return gen_lowpart (mode,
+  && new_code == NE
+  && is_int_mode (mode, &int_mode)
+  && op1 == const0_rtx
+  && int_mode == GET_MODE (op0)
+  && nonzero_bits (op0, int_mode) == 1)
+   return gen_lowpart (int_mode,
expand_compound_operation (op0));
 
  else if (STORE_FLAG_VALUE == 1
-  && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
+  && new_code == NE
+  && is_int_mode (mode, &int_mode)
   && op1 == const0_rtx
-  && mode == GET_MODE (op0)
-  && (num_sign_bit_copies (op0, mode)
-  == GET_MODE_PRECISION (mode)))
+  && int_mode == GET_MODE (op0)
+  && (num_sign_bit_copies (op0, int_mode)
+  == GET_MODE_PRECISION (int_mode)))
{
  op0 = expand_compound_operation (op0);
- return simplify_gen_unary (NEG, mode,
-gen_lowpart (mode, op0),
-mode);
+ return simplify_gen_unary (NEG, int_mode,
+gen_lowpart (int_mode, op0),
+int_mode);
}
 
  else if (STORE_FLAG_VALUE == 1
-  && new_code == EQ && GET_MODE_CLASS (mode) == MODE_INT
+  && new_code == EQ
+  && is_int_mode (mode, &int_mode)
   && op1 == const0_rtx
-  && mode == GET_MODE (op0)
-  && nonz

[21/67] Replace SCALAR_INT_MODE_P checks with is_a

2016-12-09 Thread Richard Sandiford
Replace checks of "SCALAR_INT_MODE_P (...)" with
"is_a  (..., &var)" in cases where it
becomes useful to refer to the mode as a scalar_int_mode.
Also:

- Replace some lingering checks for the two constituent
  classes (MODE_INT and MODE_PARTIAL_INT)

- Introduce is_a  checks for some uses of
  HWI_COMPUTABLE_MODE_P, which is a subcondition of
  SCALAR_INT_MODE_P.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* wide-int.h (int_traits) New class.
(int_traits) Likewise.
* cfgexpand.c (expand_debug_expr): Use is_a .
Use GET_MODE_UNIT_PRECISION and remove redundant test for
SCALAR_INT_MODE_P.
* combine.c (set_nonzero_bits_and_sign_copies): Use
is_a .
(find_split_point): Likewise.
(combine_simplify_rtx): Likewise.
(simplify_logical): Likewise.
(expand_compound_operation): Likewise.
(expand_field_assignment): Likewise.
(make_compound_operation): Likewise.
(extended_count): Likewise.
(change_zero_ext): Likewise.
(simplify_comparison): Likewise.
* dwarf2out.c (scompare_loc_descriptor): Likewise.
(ucompare_loc_descriptor): Likewise.
(minmax_loc_descriptor): Likewise.
(mem_loc_descriptor): Likewise.
(loc_descriptor): Likewise.
* expmed.c (init_expmed_one_mode): Likewise.
* lra-constraints.c (lra_constraint_offset): Likewise.
* optabs.c (prepare_libcall_arg): Likewise.
* postreload.c (move2add_note_store): Likewise.
* reload.c (operands_match_p): Likewise.
* rtl.h (load_extend_op): Likewise.
* rtlhooks.c (gen_lowpart_general): Likewise.
* simplify-rtx.c (simplify_truncation): Likewise.
(simplify_unary_operation_1): Likewise.
(simplify_binary_operation_1): Likewise.
(simplify_const_binary_operation): Likewise.
(simplify_const_relational_operation): Likewise.
(simplify_subreg): Likewise.
* stor-layout.c (bitwise_mode_for_mode): Likewise.
* var-tracking.c (adjust_mems): Likewise.
(prepare_call_arguments): Likewise.

gcc/ada/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* gcc-interface/decl.c (check_ok_for_atomic_type): Use
is_a .
* gcc-interface/trans.c (Pragma_to_gnu): Likewise.
* gcc-interface/utils.c (gnat_type_for_mode): Likewise.

gcc/fortran/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* trans-types.c (gfc_type_for_mode): Use is_a .

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 843024e..e300892 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -8753,9 +8753,10 @@ check_ok_for_atomic_type (tree type, Entity_Id 
gnat_entity, bool component_p)
 
   /* Consider all aligned floating-point types atomic and any aligned types
  that are represented by integers no wider than a machine word.  */
+  scalar_int_mode int_mode;
   if ((mclass == MODE_FLOAT
-   || ((mclass == MODE_INT || mclass == MODE_PARTIAL_INT)
-  && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD))
+   || (is_a  (mode, &int_mode)
+  && GET_MODE_BITSIZE (int_mode) <= BITS_PER_WORD))
   && align >= GET_MODE_ALIGNMENT (mode))
 return;
 
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index e5047f0..da4408e 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -1268,6 +1268,7 @@ Pragma_to_gnu (Node_Id gnat_node)
  tree gnu_expr = gnat_to_gnu (gnat_expr);
  int use_address;
  machine_mode mode;
+ scalar_int_mode int_mode;
  tree asm_constraint = NULL_TREE;
 #ifdef ASM_COMMENT_START
  char *comment;
@@ -1279,9 +1280,8 @@ Pragma_to_gnu (Node_Id gnat_node)
  /* Use the value only if it fits into a normal register,
 otherwise use the address.  */
  mode = TYPE_MODE (TREE_TYPE (gnu_expr));
- use_address = ((GET_MODE_CLASS (mode) != MODE_INT
- && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
-|| GET_MODE_SIZE (mode) > UNITS_PER_WORD);
+ use_address = (!is_a  (mode, &int_mode)
+|| GET_MODE_SIZE (int_mode) > UNITS_PER_WORD);
 
  if (use_address)
gnu_expr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr);
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 937691c..4e0b7fe5 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -3417,8 +3417,9 @@ gnat_type_for_mode (machine_mode mode, int unsignedp)
 return float_type_for_precision (GET_MODE_PRECISION (float_mode),
 float_mode);
 
-  if (SCALAR_INT_MODE_P (mode))
-return gnat_type_for_size (GET_MODE_BITSIZE (mode), unsignedp);
+  scalar

[22/67] Replace !VECTOR_MODE_P with is_a

2016-12-09 Thread Richard Sandiford
This patch replaces some checks of !VECTOR_MODE_P with checks
of is_a , in cases where the scalar integer
modes were the only useful alternatives left.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* simplify-rtx.c (simplify_binary_operation_1): Use
is_a  instead of !VECTOR_MODE_P.

diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index cb0e43d..e5e7a71 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2124,7 +2124,7 @@ simplify_binary_operation_1 (enum rtx_code code, 
machine_mode mode,
   rtx tem, reversed, opleft, opright;
   HOST_WIDE_INT val;
   unsigned int width = GET_MODE_PRECISION (mode);
-  scalar_int_mode int_mode;
+  scalar_int_mode int_mode, inner_mode;
 
   /* Even if we can't compute a constant result,
  there are some cases worth simplifying.  */
@@ -3357,27 +3357,24 @@ simplify_binary_operation_1 (enum rtx_code code, 
machine_mode mode,
 (subreg:M1 (ashiftrt:M2 (reg:M2) (const_int ))
).  */
   if (code == ASHIFTRT
- && !VECTOR_MODE_P (mode)
+ && is_a  (mode, &int_mode)
  && SUBREG_P (op0)
  && CONST_INT_P (op1)
  && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
- && !VECTOR_MODE_P (GET_MODE (SUBREG_REG (op0)))
+ && is_a  (GET_MODE (SUBREG_REG (op0)),
+&inner_mode)
  && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
- && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
- > GET_MODE_BITSIZE (mode))
+ && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
  && (INTVAL (XEXP (SUBREG_REG (op0), 1))
- == (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
- - GET_MODE_BITSIZE (mode)))
+ == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
  && subreg_lowpart_p (op0))
{
  rtx tmp = GEN_INT (INTVAL (XEXP (SUBREG_REG (op0), 1))
 + INTVAL (op1));
- machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
- tmp = simplify_gen_binary (ASHIFTRT,
-GET_MODE (SUBREG_REG (op0)),
+ tmp = simplify_gen_binary (ASHIFTRT, inner_mode,
 XEXP (SUBREG_REG (op0), 0),
 tmp);
- return lowpart_subreg (mode, tmp, inner_mode);
+ return lowpart_subreg (int_mode, tmp, inner_mode);
}
 canonicalize_shift:
   if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))



[23/67] Replace != VOIDmode checks with is_a

2016-12-09 Thread Richard Sandiford
This patch replaces some checks against VOIDmode with checks
of is_a , in cases where scalar integer modes
were the only useful alternatives left.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* cfgexpand.c (expand_debug_expr): Use is_a 
instead of != VOIDmode.
* combine.c (if_then_else_cond): Likewise.
* dwarf2out.c (mem_loc_descriptor): Likewise.
* rtlanal.c (canonicalize_condition): Likewise.
* simplify-rtx.c (simplify_relational_operation_1): Likewise.

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index f94be27..1427a97 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4128,7 +4128,7 @@ expand_debug_expr (tree exp)
   machine_mode inner_mode = VOIDmode;
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
   addr_space_t as;
-  scalar_int_mode op1_mode;
+  scalar_int_mode op0_mode, op1_mode;
 
   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
 {
@@ -4570,23 +4570,23 @@ expand_debug_expr (tree exp)
 size_t, we need to check for mis-matched modes and correct
 the addend.  */
   if (op0 && op1
- && GET_MODE (op0) != VOIDmode && GET_MODE (op1) != VOIDmode
- && GET_MODE (op0) != GET_MODE (op1))
+ && is_a  (GET_MODE (op0), &op0_mode)
+ && is_a  (GET_MODE (op1), &op1_mode)
+ && op0_mode != op1_mode)
{
- if (GET_MODE_BITSIZE (GET_MODE (op0)) < GET_MODE_BITSIZE (GET_MODE 
(op1))
- /* If OP0 is a partial mode, then we must truncate, even if it has
-the same bitsize as OP1 as GCC's representation of partial 
modes
-is opaque.  */
- || (GET_MODE_CLASS (GET_MODE (op0)) == MODE_PARTIAL_INT
- && GET_MODE_BITSIZE (GET_MODE (op0)) == GET_MODE_BITSIZE 
(GET_MODE (op1
-   op1 = simplify_gen_unary (TRUNCATE, GET_MODE (op0), op1,
- GET_MODE (op1));
+ if (GET_MODE_BITSIZE (op0_mode) < GET_MODE_BITSIZE (op1_mode)
+ /* If OP0 is a partial mode, then we must truncate, even
+if it has the same bitsize as OP1 as GCC's
+representation of partial modes is opaque.  */
+ || (GET_MODE_CLASS (op0_mode) == MODE_PARTIAL_INT
+ && (GET_MODE_BITSIZE (op0_mode)
+ == GET_MODE_BITSIZE (op1_mode
+   op1 = simplify_gen_unary (TRUNCATE, op0_mode, op1, op1_mode);
  else
/* We always sign-extend, regardless of the signedness of
   the operand, because the operand is always unsigned
   here even if the original C expression is signed.  */
-   op1 = simplify_gen_unary (SIGN_EXTEND, GET_MODE (op0), op1,
- GET_MODE (op1));
+   op1 = simplify_gen_unary (SIGN_EXTEND, op0_mode, op1, op1_mode);
}
   /* Fall through.  */
 case PLUS_EXPR:
diff --git a/gcc/combine.c b/gcc/combine.c
index 2e2acea..8883194 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -9014,6 +9014,7 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
   enum rtx_code code = GET_CODE (x);
   rtx cond0, cond1, true0, true1, false0, false1;
   unsigned HOST_WIDE_INT nz;
+  scalar_int_mode int_mode;
 
   /* If we are comparing a value against zero, we are done.  */
   if ((code == NE || code == EQ)
@@ -9190,8 +9191,9 @@ if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
   /* If X is known to be either 0 or -1, those are the true and
  false values when testing X.  */
   else if (x == constm1_rtx || x == const0_rtx
-  || (mode != VOIDmode && mode != BLKmode
-  && num_sign_bit_copies (x, mode) == GET_MODE_PRECISION (mode)))
+  || (is_a  (mode, &int_mode)
+  && (num_sign_bit_copies (x, int_mode)
+  == GET_MODE_PRECISION (int_mode
 {
   *ptrue = constm1_rtx, *pfalse = const0_rtx;
   return x;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 19e6d24..7bf210d 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -14491,7 +14491,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
   if (mode != GET_MODE (rtl) && GET_MODE (rtl) != VOIDmode)
 return NULL;
 
-  scalar_int_mode int_mode, inner_mode;
+  scalar_int_mode int_mode, inner_mode, op1_mode;
   switch (GET_CODE (rtl))
 {
 case POST_INC:
@@ -14929,9 +14929,8 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
VAR_INIT_STATUS_INITIALIZED);
   {
rtx rtlop1 = XEXP (rtl, 1);
-   if (GET_MODE (rtlop1) != VOIDmode
-   && GET_MODE_BITSIZE (GET_MODE (rtlop1))
-  < GET_MODE_BITSIZE (int_mode))
+   if (is_a  (GET_MODE (rtlop1), &op1_mode)
+   && GET_MODE_BITSIZE (op1_mode) < GET_MODE_BITSIZE (int_mode))
  rtlop1 = gen_rtx_ZERO_EXTEND (int_mode, rtlop1);
op1 = mem_loc_descriptor (rtlop1, int_mode, mem_mode,
  VAR_INIT_STATUS_

[24/67] Replace a != BLKmode check with is_a

2016-12-09 Thread Richard Sandiford
This patch replaces a check against BLKmode with a check
of is_a , in a case where scalar integer
modes were the only useful alternatives left.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* gimple-fold.c (gimple_fold_builtin_memory_op): Use
is_a  instead of != BLKmode.

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index d00625b..c6b5411 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -713,31 +713,29 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
  unsigned ilen = tree_to_uhwi (len);
  if (pow2p_hwi (ilen))
{
+ scalar_int_mode mode;
  tree type = lang_hooks.types.type_for_size (ilen * 8, 1);
  if (type
- && TYPE_MODE (type) != BLKmode
- && (GET_MODE_SIZE (TYPE_MODE (type)) * BITS_PER_UNIT
- == ilen * 8)
+ && is_a  (TYPE_MODE (type), &mode)
+ && GET_MODE_SIZE (mode) * BITS_PER_UNIT == ilen * 8
  /* If the destination pointer is not aligned we must be able
 to emit an unaligned store.  */
- && (dest_align >= GET_MODE_ALIGNMENT (TYPE_MODE (type))
- || !SLOW_UNALIGNED_ACCESS (TYPE_MODE (type), dest_align)
- || (optab_handler (movmisalign_optab, TYPE_MODE (type))
+ && (dest_align >= GET_MODE_ALIGNMENT (mode)
+ || !SLOW_UNALIGNED_ACCESS (mode, dest_align)
+ || (optab_handler (movmisalign_optab, mode)
  != CODE_FOR_nothing)))
{
  tree srctype = type;
  tree desttype = type;
- if (src_align < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
+ if (src_align < GET_MODE_ALIGNMENT (mode))
srctype = build_aligned_type (type, src_align);
  tree srcmem = fold_build2 (MEM_REF, srctype, src, off0);
  tree tem = fold_const_aggregate_ref (srcmem);
  if (tem)
srcmem = tem;
- else if (src_align < GET_MODE_ALIGNMENT (TYPE_MODE (type))
-  && SLOW_UNALIGNED_ACCESS (TYPE_MODE (type),
-src_align)
-  && (optab_handler (movmisalign_optab,
- TYPE_MODE (type))
+ else if (src_align < GET_MODE_ALIGNMENT (mode)
+  && SLOW_UNALIGNED_ACCESS (mode, src_align)
+  && (optab_handler (movmisalign_optab, mode)
   == CODE_FOR_nothing))
srcmem = NULL_TREE;
  if (srcmem)
@@ -753,7 +751,7 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
  gimple_set_vuse (new_stmt, gimple_vuse (stmt));
  gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
}
- if (dest_align < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
+ if (dest_align < GET_MODE_ALIGNMENT (mode))
desttype = build_aligned_type (type, dest_align);
  new_stmt
= gimple_build_assign (fold_build2 (MEM_REF, desttype,



[25/67] Use is_a for bitmask optimisations

2016-12-09 Thread Richard Sandiford
Explicitly check for scalar_int_mode in code that checks for full-mode
bit operations.  These operations wouldn't work correctly for vector
modes, for example.  In many cases this is enforced also by checking
whether an operand is CONST_INT_P, but there were other cases where the
condition is more indirect.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* combine.c (combine_simplify_rtx): Add checks for
is_a .
(simplify_if_then_else): Likewise.
(make_field_assignment): Likewise.
(simplify_comparison): Likewise.
* ifcvt.c (noce_try_bitop): Likewise.
* loop-invariant.c (canonicalize_address_split): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.

diff --git a/gcc/combine.c b/gcc/combine.c
index 8883194..e1e8457 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5825,13 +5825,14 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int 
in_dest,
   if (!REG_P (temp)
  && ! (GET_CODE (temp) == SUBREG
&& REG_P (SUBREG_REG (temp)))
- && (i = exact_log2 (nonzero_bits (temp, mode))) >= 0)
+ && is_a  (mode, &int_mode)
+ && (i = exact_log2 (nonzero_bits (temp, int_mode))) >= 0)
{
  rtx temp1 = simplify_shift_const
-   (NULL_RTX, ASHIFTRT, mode,
-simplify_shift_const (NULL_RTX, ASHIFT, mode, temp,
-  GET_MODE_PRECISION (mode) - 1 - i),
-GET_MODE_PRECISION (mode) - 1 - i);
+   (NULL_RTX, ASHIFTRT, int_mode,
+simplify_shift_const (NULL_RTX, ASHIFT, int_mode, temp,
+  GET_MODE_PRECISION (int_mode) - 1 - i),
+GET_MODE_PRECISION (int_mode) - 1 - i);
 
  /* If all we did was surround TEMP with the two shifts, we
 haven't improved anything, so don't use it.  Otherwise,
@@ -5922,12 +5923,15 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int 
in_dest,
  && !REG_P (XEXP (x, 0))
  && ! (GET_CODE (XEXP (x, 0)) == SUBREG
&& REG_P (SUBREG_REG (XEXP (x, 0
- && nonzero_bits (XEXP (x, 0), mode) == 1)
-   return simplify_shift_const (NULL_RTX, ASHIFTRT, mode,
-  simplify_shift_const (NULL_RTX, ASHIFT, mode,
-gen_rtx_XOR (mode, XEXP (x, 0), const1_rtx),
-GET_MODE_PRECISION (mode) - 1),
-  GET_MODE_PRECISION (mode) - 1);
+ && is_a  (mode, &int_mode)
+ && nonzero_bits (XEXP (x, 0), int_mode) == 1)
+   return simplify_shift_const
+ (NULL_RTX, ASHIFTRT, int_mode,
+  simplify_shift_const (NULL_RTX, ASHIFT, int_mode,
+gen_rtx_XOR (int_mode, XEXP (x, 0),
+ const1_rtx),
+GET_MODE_PRECISION (int_mode) - 1),
+  GET_MODE_PRECISION (int_mode) - 1);
 
   /* If we are adding two things that have no bits in common, convert
 the addition into an IOR.  This will often be further simplified,
@@ -5965,11 +5969,12 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int 
in_dest,
 case MINUS:
   /* (minus  (and  (const_int -pow2))) becomes
 (and  (const_int pow2-1))  */
-  if (GET_CODE (XEXP (x, 1)) == AND
+  if (is_a  (mode, &int_mode)
+ && GET_CODE (XEXP (x, 1)) == AND
  && CONST_INT_P (XEXP (XEXP (x, 1), 1))
  && pow2p_hwi (-UINTVAL (XEXP (XEXP (x, 1), 1)))
  && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
-   return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0),
+   return simplify_and_const_int (NULL_RTX, int_mode, XEXP (x, 0),
   -INTVAL (XEXP (XEXP (x, 1), 1)) - 1);
   break;
 
@@ -6000,14 +6005,16 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, int 
in_dest,
 case UDIV:
   /* If this is a divide by a power of two, treat it as a shift if
 its first operand is a shift.  */
-  if (CONST_INT_P (XEXP (x, 1))
+  if (is_a  (mode, &int_mode)
+ && CONST_INT_P (XEXP (x, 1))
  && (i = exact_log2 (UINTVAL (XEXP (x, 1 >= 0
  && (GET_CODE (XEXP (x, 0)) == ASHIFT
  || GET_CODE (XEXP (x, 0)) == LSHIFTRT
  || GET_CODE (XEXP (x, 0)) == ASHIFTRT
  || GET_CODE (XEXP (x, 0)) == ROTATE
  || GET_CODE (XEXP (x, 0)) == ROTATERT))
-   return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (x, 0), i);
+   return simplify_shift_const (NULL_RTX, LSHIFTRT, int_mode,
+XEXP (x, 0), i);
   break;
 
 case EQ:  case NE:
@@ -6291,22 +6298,28 @@ simplify_if_then_else (rtx x)
  std::swap (true_rtx, false_rtx);
}
 
-  /* If we are comparing against zero and the expression being tested has
-only a single bit that might be nonzero, that is its value

[26/67] Use is_a in subreg/extract simplifications

2016-12-09 Thread Richard Sandiford
Add is_a  checks to various places that were
optimising subregs or extractions in ways that only made sense
for scalar integers.  Often the subreg transformations were
looking for extends, truncates or shifts and trying to remove
the subreg, which wouldn't be correct if the SUBREG_REG was
a vector rather than a scalar.

The simplify_binary_operation_1 part also removes a redundant:

  GET_MODE (opleft) == GET_MODE (XEXP (opright, 0))

since this must be true for:

  (ior A (lshifrt B ...))  A == opleft, B == XEXP (opright, 0)

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* combine.c (find_split_point): Add is_a  checks.
(make_compound_operation): Likewise.
(change_zero_ext): Likewise.
* expr.c (convert_move): Likewise.
(convert_modes): Likewise.
* fwprop.c (forward_propagate_subreg): Likewise.
* loop-iv.c (get_biv_step_1): Likewise.
* optabs.c (widen_operand): Likewise.
* postreload.c (move2add_valid_value_p): Likewise.
* recog.c (simplify_while_replacing): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
(simplify_binary_operation_1): Likewise.  Remove redundant
mode equality check.

diff --git a/gcc/combine.c b/gcc/combine.c
index e1e8457..7f943be 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -4768,7 +4768,7 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
   HOST_WIDE_INT pos = 0;
   int unsignedp = 0;
   rtx inner = NULL_RTX;
-  scalar_int_mode inner_mode;
+  scalar_int_mode mode, inner_mode;
 
   /* First special-case some codes.  */
   switch (code)
@@ -5022,7 +5022,9 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
 
case SIGN_EXTRACT:
case ZERO_EXTRACT:
- if (CONST_INT_P (XEXP (SET_SRC (x), 1))
+ if (is_a  (GET_MODE (XEXP (SET_SRC (x), 0)),
+ &inner_mode)
+ && CONST_INT_P (XEXP (SET_SRC (x), 1))
  && CONST_INT_P (XEXP (SET_SRC (x), 2)))
{
  inner = XEXP (SET_SRC (x), 0);
@@ -5030,7 +5032,7 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
  pos = INTVAL (XEXP (SET_SRC (x), 2));
 
  if (BITS_BIG_ENDIAN)
-   pos = GET_MODE_PRECISION (GET_MODE (inner)) - len - pos;
+   pos = GET_MODE_PRECISION (inner_mode) - len - pos;
  unsignedp = (code == ZERO_EXTRACT);
}
  break;
@@ -5040,10 +5042,9 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
}
 
   if (len && pos >= 0
- && pos + len <= GET_MODE_PRECISION (GET_MODE (inner)))
+ && pos + len <= GET_MODE_PRECISION (GET_MODE (inner))
+ && is_a  (GET_MODE (SET_SRC (x)), &mode))
{
- machine_mode mode = GET_MODE (SET_SRC (x));
-
  /* For unsigned, we have a choice of a shift followed by an
 AND or two shifts.  Use two shifts for field sizes where the
 constant might be too large.  We assume here that we can
@@ -7836,6 +7837,7 @@ make_compound_operation_int (machine_mode mode, rtx 
*x_ptr,
   int i;
   rtx tem;
   bool equality_comparison = false;
+  scalar_int_mode inner_mode;
 
   if (in_code == EQ)
 {
@@ -7943,11 +7945,12 @@ make_compound_operation_int (machine_mode mode, rtx 
*x_ptr,
   /* Same as previous, but for (subreg (lshiftrt ...)) in first op.  */
   else if (GET_CODE (XEXP (x, 0)) == SUBREG
   && subreg_lowpart_p (XEXP (x, 0))
+  && is_a  (GET_MODE (SUBREG_REG (XEXP (x, 0))),
+ &inner_mode)
   && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
   && (i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
{
  rtx inner_x0 = SUBREG_REG (XEXP (x, 0));
- machine_mode inner_mode = GET_MODE (inner_x0);
  new_rtx = make_compound_operation (XEXP (inner_x0, 0), next_code);
  new_rtx = make_extraction (inner_mode, new_rtx, 0,
 XEXP (inner_x0, 1),
@@ -8146,10 +8149,10 @@ make_compound_operation_int (machine_mode mode, rtx 
*x_ptr,
/* If the SUBREG is masking of a logical right shift,
   make an extraction.  */
if (GET_CODE (inner) == LSHIFTRT
+   && is_a  (GET_MODE (inner), &inner_mode)
+   && GET_MODE_SIZE (mode) < GET_MODE_SIZE (inner_mode)
&& CONST_INT_P (XEXP (inner, 1))
-   && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
-   && (UINTVAL (XEXP (inner, 1))
-   < GET_MODE_PRECISION (GET_MODE (inner)))
+   && UINTVAL (XEXP (inner, 1)) < GET_MODE_PRECISION (inner_mode)
&& subreg_lowpart_p (x))
  {
new_rtx = make_compound_operation (XEXP (inner, 0), next_code);
@@ -11324,15 +11327,16 @@ change_zero_ext (rtx pat)
   maybe_swap_commutative_operands (**iter);
 
   rtx *dst = &

[27/67] Use is_a before LOAD_EXTEND_OP

2016-12-09 Thread Richard Sandiford
Add is_a  checks before load_extend_op/
LOAD_EXTEND_OP calls, if that becomes useful for later patches.
(load_extend_op will return UNKNOWN for any other type of mode.)

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* cse.c (cse_insn): Add is_a  checks.
* reload.c (push_reload): Likewise.

diff --git a/gcc/cse.c b/gcc/cse.c
index cc29d4a..e3fda8e 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4923,7 +4923,8 @@ cse_insn (rtx_insn *insn)
   rtx_code extend_op;
   if (flag_expensive_optimizations && src_related == 0
  && MEM_P (src) && ! do_not_record
- && (extend_op = load_extend_op (mode)) != UNKNOWN)
+ && is_a  (mode, &int_mode)
+ && (extend_op = load_extend_op (int_mode)) != UNKNOWN)
{
  struct rtx_def memory_extend_buf;
  rtx memory_extend_rtx = &memory_extend_buf;
@@ -4935,7 +4936,7 @@ cse_insn (rtx_insn *insn)
  PUT_CODE (memory_extend_rtx, extend_op);
  XEXP (memory_extend_rtx, 0) = src;
 
- FOR_EACH_WIDER_MODE (tmode, mode)
+ FOR_EACH_WIDER_MODE (tmode, int_mode)
{
  struct table_elt *larger_elt;
 
@@ -4952,7 +4953,7 @@ cse_insn (rtx_insn *insn)
   larger_elt; larger_elt = larger_elt->next_same_value)
if (REG_P (larger_elt->exp))
  {
-   src_related = gen_lowpart (mode, larger_elt->exp);
+   src_related = gen_lowpart (int_mode, larger_elt->exp);
break;
  }
 
diff --git a/gcc/reload.c b/gcc/reload.c
index 4d75fda..a513cf4 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1050,6 +1050,9 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
  register class.  But if it is inside a STRICT_LOW_PART, we have
  no choice, so we hope we do get the right register class there.  */
 
+#ifdef LOAD_EXTEND_OP
+  scalar_int_mode inner_int_mode;
+#endif
   if (in != 0 && GET_CODE (in) == SUBREG
   && (subreg_lowpart_p (in) || strict_low)
 #ifdef CANNOT_CHANGE_MODE_CLASS
@@ -1065,12 +1068,12 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
  && ((GET_MODE_PRECISION (inmode)
   > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in
  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
- <= UNITS_PER_WORD)
+ && is_a  (GET_MODE (SUBREG_REG (in)),
+&inner_int_mode)
+ && GET_MODE_SIZE (inner_int_mode) <= UNITS_PER_WORD
  && (GET_MODE_PRECISION (inmode)
- > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in
- && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
- && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
+ > GET_MODE_PRECISION (inner_int_mode))
+ && LOAD_EXTEND_OP (inner_int_mode) != UNKNOWN)
  || (WORD_REGISTER_OPERATIONS
  && (GET_MODE_PRECISION (inmode)
  < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in
@@ -3108,6 +3111,9 @@ find_reloads (rtx_insn *insn, int replace, int 
ind_levels, int live_known,
  operand = SUBREG_REG (operand);
  /* Force reload if this is a constant or PLUS or if there may
 be a problem accessing OPERAND in the outer mode.  */
+#ifdef LOAD_EXTEND_OP
+ scalar_int_mode int_mode;
+#endif
  if (CONSTANT_P (operand)
  || GET_CODE (operand) == PLUS
  /* We must force a reload of paradoxical SUBREGs
@@ -3145,13 +3151,13 @@ find_reloads (rtx_insn *insn, int replace, int 
ind_levels, int live_known,
  || BYTES_BIG_ENDIAN
  || ((GET_MODE_SIZE (operand_mode[i])
   <= UNITS_PER_WORD)
- && (GET_MODE_SIZE (GET_MODE (operand))
+ && (is_a 
+ (GET_MODE (operand), &int_mode))
+ && (GET_MODE_SIZE (int_mode)
  <= UNITS_PER_WORD)
  && (GET_MODE_SIZE (operand_mode[i])
- > GET_MODE_SIZE (GET_MODE (operand)))
- && INTEGRAL_MODE_P (GET_MODE (operand))
- && LOAD_EXTEND_OP (GET_MODE (operand))
-!= UNKNOWN)))
+ > GET_MODE_SIZE (int_mode))
+ && LOAD_EXTEND_OP (int_mode) != UNKNOWN)))
  )
force_reload = 1;
}



[28/67] Use is_a for miscellaneous types of test

2016-12-09 Thread Richard Sandiford
This patch adds is_a  checks to various places
that were explicitly or implicitly restricted to integers already,
in cases where adding an explicit is_a  is useful
for later patches.

In simplify_if_then_else, the:

  GET_MODE (XEXP (XEXP (t, 0), N))

expressions were equivalent to:

  GET_MODE (XEXP (t, 0))

due to the type of operation.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* combine.c (sign_extend_short_imm): Add is_a 
checks.
(try_combine): Likewise.
(simplify_if_then_else): Likewise.
* cse.c (cse_insn): Likewise.
* dwarf2out.c (mem_loc_descriptor): Likewise.
* emit-rtl.c (gen_lowpart_common): Likewise.
* simplify-rtx.c (simplify_truncation): Likewise.
(simplify_ternary_operation): Likewise.
* tree-ssa-loop-ivopts.c (force_expr_to_var_cost): Likewise.

diff --git a/gcc/combine.c b/gcc/combine.c
index 7f943be..92b2ec9 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1631,11 +1631,13 @@ setup_incoming_promotions (rtx_insn *first)
 static rtx
 sign_extend_short_imm (rtx src, machine_mode mode, unsigned int prec)
 {
-  if (GET_MODE_PRECISION (mode) < prec
-  && CONST_INT_P (src)
+  scalar_int_mode int_mode;
+  if (CONST_INT_P (src)
+  && is_a  (mode, &int_mode)
+  && GET_MODE_PRECISION (int_mode) < prec
   && INTVAL (src) > 0
-  && val_signbit_known_set_p (mode, INTVAL (src)))
-src = GEN_INT (INTVAL (src) | ~GET_MODE_MASK (mode));
+  && val_signbit_known_set_p (int_mode, INTVAL (src)))
+src = GEN_INT (INTVAL (src) | ~GET_MODE_MASK (int_mode));
 
   return src;
 }
@@ -3150,6 +3152,7 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, 
rtx_insn *i0,
   rtx op0 = i2src, op1 = XEXP (SET_SRC (PATTERN (i3)), 1);
   machine_mode compare_mode, orig_compare_mode;
   enum rtx_code compare_code = UNKNOWN, orig_compare_code = UNKNOWN;
+  scalar_int_mode mode;
 
   newpat = PATTERN (i3);
   newpat_dest = SET_DEST (newpat);
@@ -3160,8 +3163,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, 
rtx_insn *i0,
&cc_use_insn)))
{
  compare_code = orig_compare_code = GET_CODE (*cc_use_loc);
- compare_code = simplify_compare_const (compare_code,
-GET_MODE (i2dest), op0, &op1);
+ if (is_a  (GET_MODE (i2dest), &mode))
+   compare_code = simplify_compare_const (compare_code, mode,
+  op0, &op1);
  target_canonicalize_comparison (&compare_code, &op0, &op1, 1);
}
 
@@ -6263,7 +6267,7 @@ simplify_if_then_else (rtx x)
   int i;
   enum rtx_code false_code;
   rtx reversed;
-  scalar_int_mode int_mode;
+  scalar_int_mode int_mode, inner_mode;
 
   /* Simplify storing of the truth value.  */
   if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
@@ -6458,7 +6462,7 @@ simplify_if_then_else (rtx x)
   rtx cond_op0 = XEXP (cond, 0);
   rtx cond_op1 = XEXP (cond, 1);
   enum rtx_code op = UNKNOWN, extend_op = UNKNOWN;
-  machine_mode m = int_mode;
+  scalar_int_mode m = int_mode;
   rtx z = 0, c1 = NULL_RTX;
 
   if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS
@@ -6475,6 +6479,7 @@ simplify_if_then_else (rtx x)
   && rtx_equal_p (XEXP (t, 1), f))
c1 = XEXP (t, 0), op = GET_CODE (t), z = f;
   else if (GET_CODE (t) == SIGN_EXTEND
+  && is_a  (GET_MODE (XEXP (t, 0)), &inner_mode)
   && (GET_CODE (XEXP (t, 0)) == PLUS
   || GET_CODE (XEXP (t, 0)) == MINUS
   || GET_CODE (XEXP (t, 0)) == IOR
@@ -6488,13 +6493,14 @@ simplify_if_then_else (rtx x)
   && (num_sign_bit_copies (f, GET_MODE (f))
   > (unsigned int)
 (GET_MODE_PRECISION (int_mode)
- - GET_MODE_PRECISION (GET_MODE (XEXP (XEXP (t, 0), 0))
+ - GET_MODE_PRECISION (inner_mode
{
  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
  extend_op = SIGN_EXTEND;
- m = GET_MODE (XEXP (t, 0));
+ m = inner_mode;
}
   else if (GET_CODE (t) == SIGN_EXTEND
+  && is_a  (GET_MODE (XEXP (t, 0)), &inner_mode)
   && (GET_CODE (XEXP (t, 0)) == PLUS
   || GET_CODE (XEXP (t, 0)) == IOR
   || GET_CODE (XEXP (t, 0)) == XOR)
@@ -6504,13 +6510,14 @@ simplify_if_then_else (rtx x)
   && (num_sign_bit_copies (f, GET_MODE (f))
   > (unsigned int)
 (GET_MODE_PRECISION (int_mode)
- - GET_MODE_PRECISION (GET_MODE (XEXP (XEXP (t, 0), 1))
+ - GET_MODE_PRECISION (inner_mode
{
  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
  extend_op = SIGN_EXTEN

[29/67] Make some *_loc_descriptor helpers take scalar_int_mode

2016-12-09 Thread Richard Sandiford
The *_loc_descriptor routines for clz, popcount, bswap and rotate
all required SCALAR_INT_MODE_P.  This patch moves the checks into
the caller (mem_loc_descriptor) so that the types of the mode
parameters can be scalar_int_mode instead of machine_mode.

The MOD handling in mem_loc_descriptor is also specific to
scalar integer modes.  Adding an explicit check allows
typed_binop to take a scalar_int_mode too.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* dwarf2out.c (typed_binop): Change mode parameter to scalar_int_mode.
(clz_loc_descriptor): Likewise.  Remove SCALAR_INT_MODE_P check.
(popcount_loc_descriptor): Likewise.
(bswap_loc_descriptor): Likewise.
(rotate_loc_descriptor): Likewise.
(mem_loc_descriptor): Add is_a  checks before
calling the functions above.

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 0b8b12d..ed5ec24 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -14040,7 +14040,7 @@ minmax_loc_descriptor (rtx rtl, machine_mode mode,
 
 static dw_loc_descr_ref
 typed_binop (enum dwarf_location_atom op, rtx rtl, dw_die_ref type_die,
-machine_mode mode, machine_mode mem_mode)
+scalar_int_mode mode, machine_mode mem_mode)
 {
   dw_loc_descr_ref cvt, op0, op1;
 
@@ -14096,7 +14096,7 @@ typed_binop (enum dwarf_location_atom op, rtx rtl, 
dw_die_ref type_die,
L4: DW_OP_nop  */
 
 static dw_loc_descr_ref
-clz_loc_descriptor (rtx rtl, machine_mode mode,
+clz_loc_descriptor (rtx rtl, scalar_int_mode mode,
machine_mode mem_mode)
 {
   dw_loc_descr_ref op0, ret, tmp;
@@ -14107,8 +14107,7 @@ clz_loc_descriptor (rtx rtl, machine_mode mode,
   dw_loc_descr_ref l4jump, l4label;
   rtx msb;
 
-  if (!SCALAR_INT_MODE_P (mode)
-  || GET_MODE (XEXP (rtl, 0)) != mode)
+  if (GET_MODE (XEXP (rtl, 0)) != mode)
 return NULL;
 
   op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
@@ -14208,15 +14207,14 @@ clz_loc_descriptor (rtx rtl, machine_mode mode,
L2: DW_OP_drop  */
 
 static dw_loc_descr_ref
-popcount_loc_descriptor (rtx rtl, machine_mode mode,
+popcount_loc_descriptor (rtx rtl, scalar_int_mode mode,
 machine_mode mem_mode)
 {
   dw_loc_descr_ref op0, ret, tmp;
   dw_loc_descr_ref l1jump, l1label;
   dw_loc_descr_ref l2jump, l2label;
 
-  if (!SCALAR_INT_MODE_P (mode)
-  || GET_MODE (XEXP (rtl, 0)) != mode)
+  if (GET_MODE (XEXP (rtl, 0)) != mode)
 return NULL;
 
   op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
@@ -14269,17 +14267,16 @@ popcount_loc_descriptor (rtx rtl, machine_mode mode,
L2: DW_OP_drop DW_OP_swap DW_OP_drop  */
 
 static dw_loc_descr_ref
-bswap_loc_descriptor (rtx rtl, machine_mode mode,
+bswap_loc_descriptor (rtx rtl, scalar_int_mode mode,
  machine_mode mem_mode)
 {
   dw_loc_descr_ref op0, ret, tmp;
   dw_loc_descr_ref l1jump, l1label;
   dw_loc_descr_ref l2jump, l2label;
 
-  if (!SCALAR_INT_MODE_P (mode)
-  || BITS_PER_UNIT != 8
+  if (BITS_PER_UNIT != 8
   || (GET_MODE_BITSIZE (mode) != 32
- &&  GET_MODE_BITSIZE (mode) != 64))
+ && GET_MODE_BITSIZE (mode) != 64))
 return NULL;
 
   op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
@@ -14354,16 +14351,13 @@ bswap_loc_descriptor (rtx rtl, machine_mode mode,
[ DW_OP_swap constMASK DW_OP_and DW_OP_swap ] DW_OP_shr DW_OP_or  */
 
 static dw_loc_descr_ref
-rotate_loc_descriptor (rtx rtl, machine_mode mode,
+rotate_loc_descriptor (rtx rtl, scalar_int_mode mode,
   machine_mode mem_mode)
 {
   rtx rtlop1 = XEXP (rtl, 1);
   dw_loc_descr_ref op0, op1, ret, mask[2] = { NULL, NULL };
   int i;
 
-  if (!SCALAR_INT_MODE_P (mode))
-return NULL;
-
   if (GET_MODE (rtlop1) != VOIDmode
   && GET_MODE_BITSIZE (GET_MODE (rtlop1)) < GET_MODE_BITSIZE (mode))
 rtlop1 = gen_rtx_ZERO_EXTEND (mode, rtlop1);
@@ -14969,12 +14963,13 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
   break;
 
 case MOD:
-  if (GET_MODE_SIZE (mode) > DWARF2_ADDR_SIZE
- && (!dwarf_strict || dwarf_version >= 5))
+  if ((!dwarf_strict || dwarf_version >= 5)
+ && is_a  (mode, &int_mode)
+ && GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
{
  mem_loc_result = typed_binop (DW_OP_mod, rtl,
base_type_for_mode (mode, 0),
-   mode, mem_mode);
+   int_mode, mem_mode);
  break;
}
 
@@ -15326,21 +15321,25 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
 case CLZ:
 case CTZ:
 case FFS:
-  mem_loc_result = clz_loc_descriptor (rtl, mode, mem_mode);
+  if (is_a  (mode, &int_mode))
+   mem_loc_result = clz_loc_descriptor (rtl, int_mode, mem_mode);
   break;
 
 case POPCOUNT:
 case PARITY:
-  mem_loc_result = popcount_loc_descriptor (rtl, mode, mem_mode);
+  i

[30/67] Use scalar_int_mode for doubleword splits

2016-12-09 Thread Richard Sandiford
Add is_a  tests to a couple of places that
were splitting doubleword integer operations into word_mode
operations.  Also use scalar_int_mode in the expand_expr_real_2
handling of doubleword shifts.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* expr.c (expand_expr_real_2): Use scalar_int_mode for the
double-word mode.
* lower-subreg.c (resolve_shift_zext): Use is_a .
* optabs.c (expand_unop): Likewise.

diff --git a/gcc/expr.c b/gcc/expr.c
index 843c402..0d88e41 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8197,6 +8197,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode 
tmode,
   tree type;
   int unsignedp;
   machine_mode mode;
+  scalar_int_mode int_mode;
   enum tree_code code = ops->code;
   optab this_optab;
   rtx subtarget, original_target;
@@ -9102,8 +9103,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode 
tmode,
&& target
&& REG_P (target)
&& ! unsignedp
-   && mode == GET_MODE_WIDER_MODE (word_mode).else_void ()
-   && GET_MODE_SIZE (mode) == 2 * GET_MODE_SIZE (word_mode)
+   && GET_MODE_2XWIDER_MODE (word_mode).exists (&int_mode)
+   && mode == int_mode
&& TREE_CONSTANT (treeop1)
&& TREE_CODE (treeop0) == SSA_NAME)
  {
@@ -9114,18 +9115,18 @@ expand_expr_real_2 (sepops ops, rtx target, 
machine_mode tmode,
machine_mode rmode = TYPE_MODE
  (TREE_TYPE (gimple_assign_rhs1 (def)));
 
-   if (GET_MODE_SIZE (rmode) < GET_MODE_SIZE (mode)
+   if (GET_MODE_SIZE (rmode) < GET_MODE_SIZE (int_mode)
&& TREE_INT_CST_LOW (treeop1) < GET_MODE_BITSIZE (word_mode)
&& ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (rmode))
>= GET_MODE_BITSIZE (word_mode)))
  {
rtx_insn *seq, *seq_old;
unsigned int high_off = subreg_highpart_offset (word_mode,
-   mode);
-   rtx low = lowpart_subreg (word_mode, op0, mode);
-   rtx dest_low = lowpart_subreg (word_mode, target, mode);
+   int_mode);
+   rtx low = lowpart_subreg (word_mode, op0, int_mode);
+   rtx dest_low = lowpart_subreg (word_mode, target, int_mode);
rtx dest_high = simplify_gen_subreg (word_mode, target,
-mode, high_off);
+int_mode, high_off);
HOST_WIDE_INT ramount = (BITS_PER_WORD
 - TREE_INT_CST_LOW (treeop1));
tree rshift = build_int_cst (TREE_TYPE (treeop1), ramount);
@@ -9147,12 +9148,13 @@ expand_expr_real_2 (sepops ops, rtx target, 
machine_mode tmode,
end_sequence ();
temp = target ;
 
-   if (have_insn_for (ASHIFT, mode))
+   if (have_insn_for (ASHIFT, int_mode))
  {
bool speed_p = optimize_insn_for_speed_p ();
start_sequence ();
-   rtx ret_old = expand_variable_shift (code, mode, op0,
-treeop1, target,
+   rtx ret_old = expand_variable_shift (code, int_mode,
+op0, treeop1,
+target,
 unsignedp);
 
seq_old = get_insns ();
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 520eed1..f82bb87 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -1225,6 +1225,7 @@ resolve_shift_zext (rtx_insn *insn)
   rtx_insn *insns;
   rtx src_reg, dest_reg, dest_upper, upper_src = NULL_RTX;
   int src_reg_num, dest_reg_num, offset1, offset2, src_offset;
+  scalar_int_mode inner_mode;
 
   set = single_set (insn);
   if (!set)
@@ -1238,6 +1239,8 @@ resolve_shift_zext (rtx_insn *insn)
 return NULL;
 
   op_operand = XEXP (op, 0);
+  if (!is_a  (GET_MODE (op_operand), &inner_mode))
+return NULL;
 
   /* We can tear this operation apart only if the regs were already
  torn apart.  */
@@ -1250,8 +1253,7 @@ resolve_shift_zext (rtx_insn *insn)
   src_reg_num = (GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT)
? 1 : 0;
 
-  if (WORDS_BIG_ENDIAN
-  && GET_MODE_SIZE (GET_MODE (op_operand)) > UNITS_PER_WORD)
+  if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
 src_reg_num = 1 - src_reg_num;
 
   if (GET_CODE (op) == ZERO_EXTEND)
diff --git a/gcc/optabs.c b/gcc/optabs.c
index acf89bd..77ca419 100

[31/67] Use scalar_int_mode for move2add

2016-12-09 Thread Richard Sandiford
The postreload move2add optimisations are specific to scalar
integers.  This patch adds an explicit check to the main guarding
"if" and propagates the information through subroutines.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* postreload.c (move2add_valid_value_p): Change type of mode
parameter to scalar_int_mode.
(move2add_use_add2_insn): Add a mode parameter and use it instead
of GET_MODE (reg).
(move2add_use_add3_insn): Likewise.
(reload_cse_move2add): Update accordingly.

diff --git a/gcc/postreload.c b/gcc/postreload.c
index ff7e7c3..37669cd 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -1687,7 +1687,7 @@ move2add_record_sym_value (rtx reg, rtx sym, rtx off)
 /* Check if REGNO contains a valid value in MODE.  */
 
 static bool
-move2add_valid_value_p (int regno, machine_mode mode)
+move2add_valid_value_p (int regno, scalar_int_mode mode)
 {
   if (reg_set_luid[regno] <= move2add_last_label_luid)
 return false;
@@ -1718,21 +1718,21 @@ move2add_valid_value_p (int regno, machine_mode mode)
   return true;
 }
 
-/* This function is called with INSN that sets REG to (SYM + OFF),
-   while REG is known to already have value (SYM + offset).
+/* This function is called with INSN that sets REG (of mode MODE)
+   to (SYM + OFF), while REG is known to already have value (SYM + offset).
This function tries to change INSN into an add instruction
(set (REG) (plus (REG) (OFF - offset))) using the known value.
It also updates the information about REG's known value.
Return true if we made a change.  */
 
 static bool
-move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
+move2add_use_add2_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
+   rtx_insn *insn)
 {
   rtx pat = PATTERN (insn);
   rtx src = SET_SRC (pat);
   int regno = REGNO (reg);
-  rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno],
- GET_MODE (reg));
+  rtx new_src = gen_int_mode (UINTVAL (off) - reg_offset[regno], mode);
   bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
   bool changed = false;
 
@@ -1754,7 +1754,7 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, 
rtx_insn *insn)
   else
 {
   struct full_rtx_costs oldcst, newcst;
-  rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
+  rtx tem = gen_rtx_PLUS (mode, reg, new_src);
 
   get_full_set_rtx_cost (pat, &oldcst);
   SET_SRC (pat) = tem;
@@ -1764,10 +1764,10 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, 
rtx_insn *insn)
   if (costs_lt_p (&newcst, &oldcst, speed)
  && have_add2_insn (reg, new_src))
changed = validate_change (insn, &SET_SRC (pat), tem, 0);   
-  else if (sym == NULL_RTX && GET_MODE (reg) != BImode)
+  else if (sym == NULL_RTX && mode != BImode)
{
- machine_mode narrow_mode;
- FOR_EACH_MODE_UNTIL (narrow_mode, GET_MODE (reg))
+ scalar_int_mode narrow_mode;
+ FOR_EACH_MODE_UNTIL (narrow_mode, mode)
{
  if (have_insn_for (STRICT_LOW_PART, narrow_mode)
  && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
@@ -1797,9 +1797,9 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, 
rtx_insn *insn)
 }
 
 
-/* This function is called with INSN that sets REG to (SYM + OFF),
-   but REG doesn't have known value (SYM + offset).  This function
-   tries to find another register which is known to already have
+/* This function is called with INSN that sets REG (of mode MODE) to
+   (SYM + OFF), but REG doesn't have known value (SYM + offset).  This
+   function tries to find another register which is known to already have
value (SYM + offset) and change INSN into an add instruction
(set (REG) (plus (the found register) (OFF - offset))) if such
a register is found.  It also updates the information about
@@ -1807,7 +1807,8 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, 
rtx_insn *insn)
Return true iff we made a change.  */
 
 static bool
-move2add_use_add3_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
+move2add_use_add3_insn (scalar_int_mode mode, rtx reg, rtx sym, rtx off,
+   rtx_insn *insn)
 {
   rtx pat = PATTERN (insn);
   rtx src = SET_SRC (pat);
@@ -1826,7 +1827,7 @@ move2add_use_add3_insn (rtx reg, rtx sym, rtx off, 
rtx_insn *insn)
   SET_SRC (pat) = plus_expr;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-if (move2add_valid_value_p (i, GET_MODE (reg))
+if (move2add_valid_value_p (i, mode)
&& reg_base_reg[i] < 0
&& reg_symbol_ref[i] != NULL_RTX
&& rtx_equal_p (sym, reg_symbol_ref[i]))
@@ -1916,8 +1917,10 @@ reload_cse_move2add (rtx_insn *first)
   pat = PATTERN (insn);
   /* For simplicity, we only perform this optimization on
 straightforward SETs.  */
+  scalar_int_mode mode;
   if (GET_CODE (pat) == SET

[32/67] Check is_a before calling valid_pointer_mode

2016-12-09 Thread Richard Sandiford
A future patch will make valid_pointer_mode take a scalar_int_mode
instead of a machine_mode.  is_a <...> rather than as_a <...> is
needed here because we're checking a mode supplied by the user.

gcc/c-family/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* c-attribs.c (handle_mode_attribute): Check for a scalar_int_mode
before calling targetm.addr_space.valid_pointer_mode.

diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 4c4017a..14b43fe 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -1356,10 +1356,12 @@ handle_mode_attribute (tree *node, tree name, tree args,
 
   if (POINTER_TYPE_P (type))
{
+ scalar_int_mode addr_mode;
  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
  tree (*fn)(tree, machine_mode, bool);
 
- if (!targetm.addr_space.valid_pointer_mode (mode, as))
+ if (!is_a  (mode, &addr_mode)
+ || !targetm.addr_space.valid_pointer_mode (addr_mode, as))
{
  error ("invalid pointer mode %qs", p);
  return NULL_TREE;
@@ -1369,7 +1371,7 @@ handle_mode_attribute (tree *node, tree name, tree args,
fn = build_pointer_type_for_mode;
  else
fn = build_reference_type_for_mode;
- typefm = fn (TREE_TYPE (type), mode, false);
+ typefm = fn (TREE_TYPE (type), addr_mode, false);
}
   else
{



[33/67] Add a NARROWEST_INT_MODE macro

2016-12-09 Thread Richard Sandiford
Replace uses of GET_CLASS_NARROWEST_MODE (MODE_INT) with a new
NARROWEST_INT_MODE macro, which has type scalar_int_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* machmode.h (NARROWEST_INT_MODE): New macro.
* expr.c (alignment_for_piecewise_move): Use it instead of
GET_CLASS_NARROWEST_MODE (MODE_INT).
(push_block): Likewise.
* stor-layout.c (bit_field_mode_iterator::bit_field_mode_iterator):
Likewise.
* tree-vrp.c (simplify_float_conversion_using_ranges): Likewise.

gcc/ada/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* gcc-interface/decl.c (validate_size): Use NARROWEST_INT_MODE
instead of GET_CLASS_NARROWEST_MODE (MODE_INT).

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index e300892..eb21cd6 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -8526,7 +8526,7 @@ validate_size (Uint uint_size, tree gnu_type, Entity_Id 
gnat_object,
  by the smallest integral mode that's valid for pointers.  */
   if (TREE_CODE (gnu_type) == POINTER_TYPE || TYPE_IS_FAT_POINTER_P (gnu_type))
 {
-  machine_mode p_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+  scalar_int_mode p_mode = NARROWEST_INT_MODE;
   while (!targetm.valid_pointer_mode (p_mode))
p_mode = *GET_MODE_WIDER_MODE (p_mode);
   type_size = bitsize_int (GET_MODE_BITSIZE (p_mode));
diff --git a/gcc/expr.c b/gcc/expr.c
index 0d88e41..ea66027 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -705,7 +705,7 @@ alignment_for_piecewise_move (unsigned int max_pieces, 
unsigned int align)
 {
   machine_mode tmode, xmode;
 
-  xmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+  xmode = NARROWEST_INT_MODE;
   FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
{
  if (GET_MODE_SIZE (tmode) > max_pieces
@@ -3903,7 +3903,7 @@ push_block (rtx size, int extra, int below)
 negate_rtx (Pmode, size));
 }
 
-  return memory_address (GET_CLASS_NARROWEST_MODE (MODE_INT), temp);
+  return memory_address (NARROWEST_INT_MODE, temp);
 }
 
 /* A utility routine that returns the base of an auto-inc memory, or NULL.  */
diff --git a/gcc/machmode.h b/gcc/machmode.h
index fdbf174..75184b5 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -656,6 +656,11 @@ extern const unsigned char 
class_narrowest_mode[MAX_MODE_CLASS];
 #define GET_CLASS_NARROWEST_MODE(CLASS) \
   (machine_mode ((machine_mode_enum) class_narrowest_mode[CLASS]))
 
+/* The narrowest full integer mode available on the target.  */
+
+#define NARROWEST_INT_MODE \
+  (scalar_int_mode::from_int (class_narrowest_mode[MODE_INT]))
+
 /* Return the narrowest mode in T's class.  */
 
 template
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 5cf4433..a1b6c94 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -2687,7 +2687,7 @@ bit_field_mode_iterator
   HOST_WIDE_INT bitregion_start,
   HOST_WIDE_INT bitregion_end,
   unsigned int align, bool volatilep)
-: m_mode (GET_CLASS_NARROWEST_MODE (MODE_INT)), m_bitsize (bitsize),
+: m_mode (NARROWEST_INT_MODE), m_bitsize (bitsize),
   m_bitpos (bitpos), m_bitregion_start (bitregion_start),
   m_bitregion_end (bitregion_end), m_align (align),
   m_volatilep (volatilep), m_count (0)
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 88ddbf8..9a5f69d 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -9995,7 +9995,7 @@ simplify_float_conversion_using_ranges 
(gimple_stmt_iterator *gsi,
  integer mode available.  */
   else
 {
-  mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+  mode = NARROWEST_INT_MODE;
   for (;;)
{
  /* If we cannot do a signed conversion to float from mode



[34/67] Add a SCALAR_INT_TYPE_MODE macro

2016-12-09 Thread Richard Sandiford
This patch adds a SCALAR_INT_TYPE_MODE macro that asserts
that the type has a scalar integer mode and returns it as
a scalar_int_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* tree.h (SCALAR_INT_TYPE_MODE): New macro.
* builtins.c (expand_builtin_signbit): Use it.
* cfgexpand.c (expand_debug_expr): Likewise.
* dojump.c (do_jump): Likewise.
(do_compare_and_jump): Likewise.
* dwarf2cfi.c (expand_builtin_init_dwarf_reg_sizes): Likewise.
* expmed.c (make_tree): Likewise.
* expr.c (expand_expr_real_2): Likewise.
(expand_expr_real_1): Likewise.
(try_casesi): Likewise.
* fold-const-call.c (fold_const_call_ss): Likewise.
* fold-const.c (unextend): Likewise.
(extract_muldiv_1): Likewise.
(fold_single_bit_test): Likewise.
(native_encode_int): Likewise.
(native_encode_string): Likewise.
(native_interpret_int): Likewise.
* gimple-fold.c (gimple_fold_builtin_memset): Likewise.
* internal-fn.c (expand_addsub_overflow): Likewise.
(expand_neg_overflow): Likewise.
(expand_mul_overflow): Likewise.
(expand_arith_overflow): Likewise.
* match.pd: Likewise.
* stor-layout.c (layout_type): Likewise.
* tree-cfg.c (verify_gimple_assign_ternary): Likewise.
* tree-ssa-math-opts.c (convert_mult_to_widen): Likewise.
* tree-ssanames.c (get_range_info): Likewise.
* tree-switch-conversion.c (array_value_type) Likewise.:
* tree-vect-patterns.c (vect_recog_rotate_pattern): Likewise.
(vect_recog_divmod_pattern): Likewise.
(vect_recog_mixed_size_cond_pattern): Likewise.
* tree-vrp.c (extract_range_basic): Likewise.
(simplify_float_conversion_using_ranges): Likewise.
* tree.c (int_fits_type_p): Likewise.
* ubsan.c (instrument_bool_enum_load): Likewise.
* varasm.c (mergeable_string_section): Likewise.
(narrowing_initializer_constant_valid_p): Likewise.
(output_constant): Likewise.

gcc/cp/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* cvt.c (cp_convert_to_pointer): Use SCALAR_INT_TYPE_MODE.

gcc/fortran/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* target-memory.c (size_integer): Use SCALAR_INT_TYPE_MODE.
(size_logical): Likewise.

gcc/objc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* objc-encoding.c (encode_type): Use SCALAR_INT_TYPE_MODE.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 00a0a73..cf22e96 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5223,7 +5223,7 @@ expand_builtin_signbit (tree exp, rtx target)
 
   arg = CALL_EXPR_ARG (exp, 0);
   fmode = SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (arg));
-  rmode = TYPE_MODE (TREE_TYPE (exp));
+  rmode = SCALAR_INT_TYPE_MODE (TREE_TYPE (exp));
   fmt = REAL_MODE_FORMAT (fmode);
 
   arg = builtin_save_expr (arg);
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 1427a97..dbb7bca 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4128,7 +4128,7 @@ expand_debug_expr (tree exp)
   machine_mode inner_mode = VOIDmode;
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
   addr_space_t as;
-  scalar_int_mode op0_mode, op1_mode;
+  scalar_int_mode op0_mode, op1_mode, addr_mode;
 
   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
 {
@@ -4903,7 +4903,8 @@ expand_debug_expr (tree exp)
}
 
   as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
-  op0 = convert_debug_memory_address (mode, XEXP (op0, 0), as);
+  addr_mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (exp));
+  op0 = convert_debug_memory_address (addr_mode, XEXP (op0, 0), as);
 
   return op0;
 
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 400566f..971a1b0 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -234,8 +234,8 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold,
   /* Modes may be different but sizes should be the same.  There
 is supposed to be some integral type that is the same width
 as a pointer.  */
-  gcc_assert (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
- == GET_MODE_SIZE (TYPE_MODE (type)));
+  gcc_assert (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (expr)))
+ == GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type)));
 
   return convert_to_pointer_maybe_fold (type, expr, dofold);
 }
diff --git a/gcc/dojump.c b/gcc/dojump.c
index dbc76dc..749742b 100644
--- a/gcc/dojump.c
+++ b/gcc/dojump.c
@@ -575,7 +575,7 @@ do_jump (tree exp, rtx_code_label *if_false_label,
  if (TREE_CODE (shift) == INTEGER_CST
  && compare_tree_int (shift, 0) >= 0
  && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
- && prefer_and_bit_test (TYPE_MODE (argtype),
+  

[35/67] Add uses of as_a

2016-12-09 Thread Richard Sandiford
This patch adds asserting as_a  conversions
in contexts where the input is known to be a scalar integer mode.

In expand_divmod, op1 is always a scalar_int_mode if
op1_is_constant (but might not be otherwise).

In expand_binop, the patch reverses a < comparison in order to
avoid splitting a long line.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* cfgexpand.c (convert_debug_memory_address): Use
as_a .
* combine.c (expand_compound_operation): Likewise.
(make_extraction): Likewise.
(change_zero_ext): Likewise.
(simplify_comparison): Likewise.
* cse.c (cse_insn): Likewise.
* dwarf2out.c (minmax_loc_descriptor): Likewise.
(mem_loc_descriptor): Likewise.
(loc_descriptor): Likewise.
* expmed.c (synth_mult): Likewise.
(emit_store_flag_1): Likewise.
(expand_divmod): Likewise.  Use HWI_COMPUTABLE_MODE_P instead
of a comparison with size.
* expr.c (expand_assignment): Use as_a .
(reduce_to_bit_field_precision): Likewise.
* function.c (expand_function_end): Likewise.
* internal-fn.c (expand_arith_overflow_result_store): Likewise.
* loop-doloop.c (doloop_modify): Likewise.
* optabs.c (expand_binop): Likewise.
(expand_unop): Likewise.
(expand_copysign_absneg): Likewise.
(prepare_cmp_insn): Likewise.
(maybe_legitimize_operand): Likewise.
* recog.c (const_scalar_int_operand): Likewise.
* rtlanal.c (get_address_mode): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
(simplify_cond_clz_ctz): Likewise.
* tree-nested.c (get_nl_goto_field): Likewise.
* tree.c (build_vector_type_for_mode): Likewise.
* var-tracking.c (use_narrower_mode): Likewise.

gcc/c-family/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* c-common.c (c_common_type_for_mode): Use as_a .

gcc/lto/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* lto-lang.c (lto_type_for_mode): Use as_a .

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index cb04536..0e06725 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2216,15 +2216,15 @@ c_common_type_for_mode (machine_mode mode, int 
unsignedp)
   if (mode == TYPE_MODE (void_type_node))
 return void_type_node;
 
-  if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
-return (unsignedp
-   ? make_unsigned_type (GET_MODE_PRECISION (mode))
-   : make_signed_type (GET_MODE_PRECISION (mode)));
-
-  if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
-return (unsignedp
-   ? make_unsigned_type (GET_MODE_PRECISION (mode))
-   : make_signed_type (GET_MODE_PRECISION (mode)));
+  if (mode == TYPE_MODE (build_pointer_type (char_type_node))
+  || mode == TYPE_MODE (build_pointer_type (integer_type_node)))
+{
+  unsigned int precision
+   = GET_MODE_PRECISION (as_a  (mode));
+  return (unsignedp
+ ? make_unsigned_type (precision)
+ : make_signed_type (precision));
+}
 
   if (COMPLEX_MODE_P (mode))
 {
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index dbb7bca..c4863dd 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3954,12 +3954,10 @@ static rtx
 convert_debug_memory_address (machine_mode mode, rtx x,
  addr_space_t as)
 {
-  machine_mode xmode = GET_MODE (x);
-
 #ifndef POINTERS_EXTEND_UNSIGNED
   gcc_assert (mode == Pmode
  || mode == targetm.addr_space.address_mode (as));
-  gcc_assert (xmode == mode || xmode == VOIDmode);
+  gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
 #else
   rtx temp;
 
@@ -3968,6 +3966,8 @@ convert_debug_memory_address (machine_mode mode, rtx x,
   if (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode)
 return x;
 
+  /* X must have some form of address mode already.  */
+  scalar_int_mode xmode = as_a  (GET_MODE (x));
   if (GET_MODE_PRECISION (mode) < GET_MODE_PRECISION (xmode))
 x = lowpart_subreg (mode, x, xmode);
   else if (POINTERS_EXTEND_UNSIGNED > 0)
diff --git a/gcc/combine.c b/gcc/combine.c
index 92b2ec9..0f25782 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7121,16 +7121,19 @@ expand_compound_operation (rtx x)
 default:
   return x;
 }
+
+  /* We've rejected non-scalar operations by now.  */
+  scalar_int_mode mode = as_a  (GET_MODE (x));
+
   /* Convert sign extension to zero extension, if we know that the high
  bit is not set, as this is easier to optimize.  It will be converted
  back to cheaper alternative in make_extraction.  */
   if (GET_CODE (x) == SIGN_EXTEND
-  && HWI_COMPUTABLE_MODE_P (GET_MODE (x))
+  && HWI_COMPUTABLE_MODE_P (mode)
   && ((nonzero_bits (XEXP (x, 0), inner_mode)
   & ~(((unsigned HOST_WIDE

[36/67] Use scalar_int_mode in the RTL iv routines

2016-12-09 Thread Richard Sandiford
This patch changes the iv modes in rtx_iv from machine_mode
to scalar_int_mode.  It also passes the mode of the iv down
to subroutines; this avoids the previous situation in which
the mode information was sometimes lost and had to be added
by the caller on return.

Some routines already took a mode argument, but the patch
tries to standardise on passing it immediately before the
argument it describes.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* cfgloop.h (rtx_iv): Change type of extend_mode and mode to
scalar_int_mode.
(niter_desc): Likewise mode.
(iv_analyze): Add a mode parameter.
(biv_p): Likewise.
(iv_analyze_expr): Pass the mode paraeter before the rtx it describes
and change its type to scalar_int_mode.
* loop-iv.c: Update commentary at head of file.
(iv_constant): Pass the mode paraeter before the rtx it describes
and change its type to scalar_int_mode.  Remove VOIDmode handling.
(iv_subreg): Change the type of the mode parameter to scalar_int_mode.
(iv_extend): Likewise.
(shorten_into_mode): Likewise.
(iv_add): Use scalar_int_mode.
(iv_mult): Likewise.
(iv_shift): Likewise.
(canonicalize_iv_subregs): Likewise.
(get_biv_step_1): Pass the outer_mode parameter before the rx
it describes and change its to scalar_int_mode.   Also change
the type of the returned inner_mode to scalar_int_mode.
(get_biv_step): Likewise, turning outer_mode from a pointer
into a direct parameter.  Update call to get_biv_step_1.
(iv_analyze_biv): Add an outer_mode parameter.  Update calls to
iv_constant and get_biv_step.
(iv_analyze_expr): Pass the mode paraeter before the rtx it describes
and change its type to scalar_int_mode.  Don't initialise iv->mode
to VOIDmode and remove later checks for it still being VOIDmode.
Update calls to iv_analyze_op and iv_analyze_expr.  Check
is_a  when changing the mode under consideration.
(iv_analyze_def): Ignore registers that don't have a scalar_int_mode.
Update call to iv_analyze_expr.
(iv_analyze_op): Add a mode parameter.  Reject subregs whose
inner register is not also a scalar_int_mode.  Update call to
iv_analyze_biv.
(iv_analyze): Add a mode parameter.  Update call to iv_analyze_op.
(biv_p): Add a mode parameter.  Update call to iv_analyze_biv.
(iv_number_of_iterations): Use is_a  instead of
separate mode class checks.  Update calls to iv_analyze.  Remove
fix-up of VOIDmodes after iv_analyze_biv.
* loop-unroll.c (analyze_iv_to_split_insn): Reject registers that
don't have a scalar_int_mode.  Update call to biv_p.

diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 0448a61..84809c9 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -410,10 +410,10 @@ struct rtx_iv
   rtx delta, mult;
 
   /* The mode it is extended to.  */
-  machine_mode extend_mode;
+  scalar_int_mode extend_mode;
 
   /* The mode the variable iterates in.  */
-  machine_mode mode;
+  scalar_int_mode mode;
 
   /* Whether the first iteration needs to be handled specially.  */
   unsigned first_special : 1;
@@ -454,19 +454,19 @@ struct GTY(()) niter_desc
   bool signed_p;
 
   /* The mode in that niter_expr should be computed.  */
-  machine_mode mode;
+  scalar_int_mode mode;
 
   /* The number of iterations of the loop.  */
   rtx niter_expr;
 };
 
 extern void iv_analysis_loop_init (struct loop *);
-extern bool iv_analyze (rtx_insn *, rtx, struct rtx_iv *);
+extern bool iv_analyze (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *);
 extern bool iv_analyze_result (rtx_insn *, rtx, struct rtx_iv *);
-extern bool iv_analyze_expr (rtx_insn *, rtx, machine_mode,
+extern bool iv_analyze_expr (rtx_insn *, scalar_int_mode, rtx,
 struct rtx_iv *);
 extern rtx get_iv_value (struct rtx_iv *, rtx);
-extern bool biv_p (rtx_insn *, rtx);
+extern bool biv_p (rtx_insn *, scalar_int_mode, rtx);
 extern void find_simple_exit (struct loop *, struct niter_desc *);
 extern void iv_analysis_done (void);
 
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index f684da2..662b7a1 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -35,16 +35,17 @@ along with GCC; see the file COPYING3.  If not see
 
The available functions are:
 
-   iv_analyze (insn, reg, iv): Stores the description of the induction variable
- corresponding to the use of register REG in INSN to IV.  Returns true if
- REG is an induction variable in INSN. false otherwise.
- If use of REG is not found in INSN, following insns are scanned (so that
- we may call this function on insn returned by get_condition).
+   iv_analyze (insn, mode, reg, iv): Stores the description of the induction
+ variable corresponding to the use of register REG (of mode MODE) in IN

[37/67] Use scalar_int_mode when emitting cstores

2016-12-09 Thread Richard Sandiford
cstore patterns always have a scalar integer result, which has the
value 0 for "false" and STORE_FLAG_VALUE for "true".  This patch
makes that explicit using scalar_int_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* target.def (cstore_mode): Return a scalar_int_mode.
* doc/tm.texi: Regenerate.
* config/sparc/sparc.c (sparc_cstore_mode): Return a scalar_int_mode.
* targhooks.h (default_cstore_mode): Likewise.
* targhooks.c (default_cstore_mode): Likewise, using a forced
conversion.
* expmed.c (emit_cstore): Expect the target of the cstore to be
a scalar_int_mode.

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 28bb0c5..e152d62 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -646,7 +646,7 @@ static void sparc_print_operand_address (FILE *, 
machine_mode, rtx);
 static reg_class_t sparc_secondary_reload (bool, rtx, reg_class_t,
   machine_mode,
   secondary_reload_info *);
-static machine_mode sparc_cstore_mode (enum insn_code icode);
+static scalar_int_mode sparc_cstore_mode (enum insn_code icode);
 static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *);
 static bool sparc_fixed_condition_code_regs (unsigned int *, unsigned int *);
 static unsigned int sparc_min_arithmetic_precision (void);
@@ -12788,7 +12788,7 @@ sparc_modes_tieable_p (machine_mode mode1, machine_mode 
mode2)
 
 /* Implement TARGET_CSTORE_MODE.  */
 
-static machine_mode
+static scalar_int_mode
 sparc_cstore_mode (enum insn_code icode ATTRIBUTE_UNUSED)
 {
   return (TARGET_ARCH64 ? DImode : SImode);
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 4993817..05f0719 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2900,7 +2900,7 @@ This hook defines a class of registers which could be 
used for spilling  pseudos
 This hook should return @code{true} if given class of registers should  be an 
allocno class in any way.  Usually RA uses only one register  class from all 
classes containing the same register set.  In some  complicated cases, you need 
to have two or more such classes as  allocno ones for RA correct work.  Not 
defining this hook is  equivalent to returning @code{false} for all inputs.
 @end deftypefn
 
-@deftypefn {Target Hook} machine_mode TARGET_CSTORE_MODE (enum insn_code 
@var{icode})
+@deftypefn {Target Hook} scalar_int_mode TARGET_CSTORE_MODE (enum insn_code 
@var{icode})
 This hook defines the machine mode to use for the boolean result of  
conditional store patterns.  The ICODE argument is the instruction code  for 
the cstore being performed.  Not definiting this hook is the same  as accepting 
the mode encoded into operand 0 of the cstore expander  patterns.
 @end deftypefn
 
diff --git a/gcc/expmed.c b/gcc/expmed.c
index dea4923..3939c3d 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -5228,7 +5228,8 @@ emit_cstore (rtx target, enum insn_code icode, enum 
rtx_code code,
   struct expand_operand ops[4];
   rtx op0, comparison, subtarget;
   rtx_insn *last;
-  machine_mode result_mode = targetm.cstore_mode (icode);
+  scalar_int_mode result_mode = targetm.cstore_mode (icode);
+  scalar_int_mode int_target_mode;
 
   last = get_last_insn ();
   x = prepare_operand (icode, x, 2, mode, compare_mode, unsignedp);
@@ -5240,9 +5241,11 @@ emit_cstore (rtx target, enum insn_code icode, enum 
rtx_code code,
 }
 
   if (target_mode == VOIDmode)
-target_mode = result_mode;
+int_target_mode = result_mode;
+  else
+int_target_mode = as_a  (target_mode);
   if (!target)
-target = gen_reg_rtx (target_mode);
+target = gen_reg_rtx (int_target_mode);
 
   comparison = gen_rtx_fmt_ee (code, result_mode, x, y);
 
@@ -5258,20 +5261,20 @@ emit_cstore (rtx target, enum insn_code icode, enum 
rtx_code code,
   subtarget = ops[0].value;
 
   /* If we are converting to a wider mode, first convert to
- TARGET_MODE, then normalize.  This produces better combining
+ INT_TARGET_MODE, then normalize.  This produces better combining
  opportunities on machines that have a SIGN_EXTRACT when we are
  testing a single bit.  This mostly benefits the 68k.
 
  If STORE_FLAG_VALUE does not have the sign bit set when
  interpreted in MODE, we can do this conversion as unsigned, which
  is usually more efficient.  */
-  if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (result_mode))
+  if (GET_MODE_SIZE (int_target_mode) > GET_MODE_SIZE (result_mode))
 {
   convert_move (target, subtarget,
val_signbit_known_clear_p (result_mode,
   STORE_FLAG_VALUE));
   op0 = target;
-  result_mode = target_mode;
+  result_mode = int_target_mode;
 }
   else
 op0 = subtarget;
@@ -5307,7 +5310,7 @@ emit_cstore (rtx target, enum insn_code icode, enum 
rtx_code code,
 }
 

[38/67] Move SCALAR_INT_MODE_P out of strict_volatile_bitfield_p

2016-12-09 Thread Richard Sandiford
strict_volatile_bitfield_p returns false for any mode that isn't
a scalar integer.  This patch moves the check to the caller and
makes strict_volatile_bitfield_p take the mode as a scalar_int_mode.
The handling of a true return can then also use the mode as a
scalar_int_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* expmed.c (strict_volatile_bitfield_p): Change the type of fieldmode
to scalar_int_mode.  Remove check for SCALAR_INT_MODE_P.
(store_bit_field): Check is_a  before calling
strict_volatile_bitfield_p.
(extract_bit_field): Likewise.

diff --git a/gcc/expmed.c b/gcc/expmed.c
index 3939c3d..f9cdcda 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -514,7 +514,7 @@ lowpart_bit_field_p (unsigned HOST_WIDE_INT bitnum,
 static bool
 strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize,
unsigned HOST_WIDE_INT bitnum,
-   machine_mode fieldmode,
+   scalar_int_mode fieldmode,
unsigned HOST_WIDE_INT bitregion_start,
unsigned HOST_WIDE_INT bitregion_end)
 {
@@ -527,11 +527,6 @@ strict_volatile_bitfield_p (rtx op0, unsigned 
HOST_WIDE_INT bitsize,
   || flag_strict_volatile_bitfields <= 0)
 return false;
 
-  /* Non-integral modes likely only happen with packed structures.
- Punt.  */
-  if (!SCALAR_INT_MODE_P (fieldmode))
-return false;
-
   /* The bit size must not be larger than the field mode, and
  the field mode must not be larger than a word.  */
   if (bitsize > modesize || modesize > BITS_PER_WORD)
@@ -1050,19 +1045,21 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT 
bitsize,
 rtx value, bool reverse)
 {
   /* Handle -fstrict-volatile-bitfields in the cases where it applies.  */
-  if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, fieldmode,
- bitregion_start, bitregion_end))
+  scalar_int_mode int_mode;
+  if (is_a  (fieldmode, &int_mode)
+  && strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, int_mode,
+bitregion_start, bitregion_end))
 {
   /* Storing of a full word can be done with a simple store.
 We know here that the field can be accessed with one single
 instruction.  For targets that support unaligned memory,
 an unaligned access may be necessary.  */
-  if (bitsize == GET_MODE_BITSIZE (fieldmode))
+  if (bitsize == GET_MODE_BITSIZE (int_mode))
{
- str_rtx = adjust_bitfield_address (str_rtx, fieldmode,
+ str_rtx = adjust_bitfield_address (str_rtx, int_mode,
 bitnum / BITS_PER_UNIT);
  if (reverse)
-   value = flip_storage_order (fieldmode, value);
+   value = flip_storage_order (int_mode, value);
  gcc_assert (bitnum % BITS_PER_UNIT == 0);
  emit_move_insn (str_rtx, value);
}
@@ -1070,12 +1067,12 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT 
bitsize,
{
  rtx temp;
 
- str_rtx = narrow_bit_field_mem (str_rtx, fieldmode, bitsize, bitnum,
+ str_rtx = narrow_bit_field_mem (str_rtx, int_mode, bitsize, bitnum,
  &bitnum);
- gcc_assert (bitnum + bitsize <= GET_MODE_BITSIZE (fieldmode));
+ gcc_assert (bitnum + bitsize <= GET_MODE_BITSIZE (int_mode));
  temp = copy_to_reg (str_rtx);
  if (!store_bit_field_1 (temp, bitsize, bitnum, 0, 0,
- fieldmode, value, reverse, true))
+ int_mode, value, reverse, true))
gcc_unreachable ();
 
  emit_move_insn (str_rtx, temp);
@@ -1889,25 +1886,27 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT 
bitsize,
   else
 mode1 = tmode;
 
-  if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, mode1, 0, 0))
+  scalar_int_mode int_mode;
+  if (is_a  (mode1, &int_mode)
+  && strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, int_mode, 0, 0))
 {
-  /* Extraction of a full MODE1 value can be done with a simple load.
+  /* Extraction of a full INT_MODE value can be done with a simple load.
 We know here that the field can be accessed with one single
 instruction.  For targets that support unaligned memory,
 an unaligned access may be necessary.  */
-  if (bitsize == GET_MODE_BITSIZE (mode1))
+  if (bitsize == GET_MODE_BITSIZE (int_mode))
{
- rtx result = adjust_bitfield_address (str_rtx, mode1,
+ rtx result = adjust_bitfield_address (str_rtx, int_mode,
bitnum / BITS_PER_UNIT);
  if (reverse)
-   result = flip_storage_order (mode1, result);
+   result = flip_storage_order (int_mode, result);
  gcc_a

[39/67] Two changes to the get_best_mode interface

2016-12-09 Thread Richard Sandiford
get_best_mode always returns a scalar_int_mode on success,
so this patch makes that explicit in the type system.  Also,
the "largest_mode" argument is used simply to provide a maximum
size, and in practice that size is always a compile-time constant,
even when the concept of variable-sized modes is added later.
The patch therefore passes the size directly.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* machmode.h (bit_field_mode_iterator::next_mode): Take a pointer
to a scalar_int_mode instead of a machine_mode.
(bit_field_mode_iterator::m_mode): Change type to opt_scalar_int_mode.
(get_best_mode): Return a boolean and use a pointer argument to store
the selected mode.  Replace the limit mode parameter with a bit limit.
* expmed.c (adjust_bit_field_mem_for_reg): Use scalar_int_mode
for the values returned by bit_field_mode_iterator::next_mode.
(store_bit_field): Update call to get_best_mode.
(store_fixed_bit_field): Likewise.
(extract_fixed_bit_field): Likewise.
* expr.c (optimize_bitfield_assignment_op): Likewise.
* fold-const.c (optimize_bit_field_compare): Likewise.
(fold_truth_andor_1): Likewise.
* stor-layout.c (bit_field_mode_iterator::next_mode): As above.
Update for new type of m_mode.
(get_mode): As above.

diff --git a/gcc/expmed.c b/gcc/expmed.c
index f9cdcda..0b2e61a 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -459,7 +459,7 @@ adjust_bit_field_mem_for_reg (enum extraction_pattern 
pattern,
   bit_field_mode_iterator iter (bitsize, bitnum, bitregion_start,
bitregion_end, MEM_ALIGN (op0),
MEM_VOLATILE_P (op0));
-  machine_mode best_mode;
+  scalar_int_mode best_mode;
   if (iter.next_mode (&best_mode))
 {
   /* We can use a memory in BEST_MODE.  See whether this is true for
@@ -477,7 +477,7 @@ adjust_bit_field_mem_for_reg (enum extraction_pattern 
pattern,
fieldmode))
limit_mode = insn.field_mode;
 
- machine_mode wider_mode;
+ scalar_int_mode wider_mode;
  while (iter.next_mode (&wider_mode)
 && GET_MODE_SIZE (wider_mode) <= GET_MODE_SIZE (limit_mode))
best_mode = wider_mode;
@@ -1086,7 +1086,8 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT 
bitsize,
  bit region.  */
   if (MEM_P (str_rtx) && bitregion_start > 0)
 {
-  machine_mode bestmode;
+  scalar_int_mode best_mode;
+  machine_mode addr_mode = VOIDmode;
   HOST_WIDE_INT offset, size;
 
   gcc_assert ((bitregion_start % BITS_PER_UNIT) == 0);
@@ -1096,11 +1097,13 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT 
bitsize,
   size = (bitnum + bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
   bitregion_end -= bitregion_start;
   bitregion_start = 0;
-  bestmode = get_best_mode (bitsize, bitnum,
-   bitregion_start, bitregion_end,
-   MEM_ALIGN (str_rtx), VOIDmode,
-   MEM_VOLATILE_P (str_rtx));
-  str_rtx = adjust_bitfield_address_size (str_rtx, bestmode, offset, size);
+  if (get_best_mode (bitsize, bitnum,
+bitregion_start, bitregion_end,
+MEM_ALIGN (str_rtx), 0,
+MEM_VOLATILE_P (str_rtx), &best_mode))
+   addr_mode = best_mode;
+  str_rtx = adjust_bitfield_address_size (str_rtx, addr_mode,
+ offset, size);
 }
 
   if (!store_bit_field_1 (str_rtx, bitsize, bitnum,
@@ -1134,10 +1137,10 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT 
bitsize,
   if (GET_MODE_BITSIZE (mode) == 0
  || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode))
mode = word_mode;
-  mode = get_best_mode (bitsize, bitnum, bitregion_start, bitregion_end,
-   MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0));
-
-  if (mode == VOIDmode)
+  scalar_int_mode best_mode;
+  if (!get_best_mode (bitsize, bitnum, bitregion_start, bitregion_end,
+ MEM_ALIGN (op0), GET_MODE_BITSIZE (mode),
+ MEM_VOLATILE_P (op0), &best_mode))
{
  /* The only way this should occur is if the field spans word
 boundaries.  */
@@ -1146,7 +1149,7 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT 
bitsize,
  return;
}
 
-  op0 = narrow_bit_field_mem (op0, mode, bitsize, bitnum, &bitnum);
+  op0 = narrow_bit_field_mem (op0, best_mode, bitsize, bitnum, &bitnum);
 }
 
   store_fixed_bit_field_1 (op0, bitsize, bitnum, value, reverse);
@@ -1932,11 +1935,9 @@ extract_fixed_bit_field (machine_mode tmode, rtx op0,
 {
   if (MEM_P (op0))
 {
-  machine_mode mode
-   = get_best_mode (bitsize, bitnum, 

[40/67] Use scalar_int_mode for extraction_insn fields

2016-12-09 Thread Richard Sandiford
insv, extv and eztzv modify or read a field in a register or
memory.  The field always has a scalar integer mode, while the
register or memory either has a scalar integer mode or BLKmode.
The mode of the bit position is also a scalar integer.

This patch uses the type system to make that explicit.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* optabs-query.h (extraction_insn::struct_mode): Change type to
opt_scalar_int_mode and update comment.
(extraction_insn::field_mode): Change type to scalar_int_mode.
(extraction_insn::pos_mode): Likewise.
* combine.c (make_extraction): Update accordingly.
* optabs-query.c (get_traditional_extraction_insn): Likewise.
(get_optab_extraction_insn): Likewise.
* recog.c (simplify_while_replacing): Likewise.
* expmed.c (narrow_bit_field_mem): Chane the type of the mode
parameter to opt_scalar_int_mode.

diff --git a/gcc/combine.c b/gcc/combine.c
index 0f25782..449f371 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7608,7 +7608,7 @@ make_extraction (machine_mode mode, rtx inner, 
HOST_WIDE_INT pos,
   if (get_best_reg_extraction_insn (&insn, pattern,
GET_MODE_BITSIZE (inner_mode), mode))
 {
-  wanted_inner_reg_mode = insn.struct_mode;
+  wanted_inner_reg_mode = *insn.struct_mode;
   pos_mode = insn.pos_mode;
   extraction_mode = insn.field_mode;
 }
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 0b2e61a..71e1fa8 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -409,31 +409,32 @@ flip_storage_order (machine_mode mode, rtx x)
   return result;
 }
 
-/* Adjust bitfield memory MEM so that it points to the first unit of mode
-   MODE that contains a bitfield of size BITSIZE at bit position BITNUM.
-   If MODE is BLKmode, return a reference to every byte in the bitfield.
-   Set *NEW_BITNUM to the bit position of the field within the new memory.  */
+/* If MODE is set, adjust bitfield memory MEM so that it points to the
+   first unit of mode MODE that contains a bitfield of size BITSIZE at
+   bit position BITNUM.  If MODE is not set, return a BLKmode reference
+   to every byte in the bitfield.  Set *NEW_BITNUM to the bit position
+   of the field within the new memory.  */
 
 static rtx
-narrow_bit_field_mem (rtx mem, machine_mode mode,
+narrow_bit_field_mem (rtx mem, opt_scalar_int_mode mode,
  unsigned HOST_WIDE_INT bitsize,
  unsigned HOST_WIDE_INT bitnum,
  unsigned HOST_WIDE_INT *new_bitnum)
 {
-  if (mode == BLKmode)
+  if (mode.exists ())
+{
+  unsigned int unit = GET_MODE_BITSIZE (*mode);
+  *new_bitnum = bitnum % unit;
+  HOST_WIDE_INT offset = (bitnum - *new_bitnum) / BITS_PER_UNIT;
+  return adjust_bitfield_address (mem, *mode, offset);
+}
+  else
 {
   *new_bitnum = bitnum % BITS_PER_UNIT;
   HOST_WIDE_INT offset = bitnum / BITS_PER_UNIT;
   HOST_WIDE_INT size = ((*new_bitnum + bitsize + BITS_PER_UNIT - 1)
/ BITS_PER_UNIT);
-  return adjust_bitfield_address_size (mem, mode, offset, size);
-}
-  else
-{
-  unsigned int unit = GET_MODE_BITSIZE (mode);
-  *new_bitnum = bitnum % unit;
-  HOST_WIDE_INT offset = (bitnum - *new_bitnum) / BITS_PER_UNIT;
-  return adjust_bitfield_address (mem, mode, offset);
+  return adjust_bitfield_address_size (mem, BLKmode, offset, size);
 }
 }
 
diff --git a/gcc/optabs-query.c b/gcc/optabs-query.c
index e664587..6541f07 100644
--- a/gcc/optabs-query.c
+++ b/gcc/optabs-query.c
@@ -100,9 +100,14 @@ get_traditional_extraction_insn (extraction_insn *insn,
 pos_mode = word_mode;
 
   insn->icode = icode;
-  insn->field_mode = field_mode;
-  insn->struct_mode = (type == ET_unaligned_mem ? byte_mode : struct_mode);
-  insn->pos_mode = pos_mode;
+  insn->field_mode = as_a  (field_mode);
+  if (type == ET_unaligned_mem)
+insn->struct_mode = byte_mode;
+  else if (struct_mode == BLKmode)
+insn->struct_mode = opt_scalar_int_mode ();
+  else
+insn->struct_mode = as_a  (struct_mode);
+  insn->pos_mode = as_a  (pos_mode);
   return true;
 }
 
@@ -126,12 +131,17 @@ get_optab_extraction_insn (struct extraction_insn *insn,
 
   const struct insn_data_d *data = &insn_data[icode];
 
+  machine_mode pos_mode = data->operand[pos_op].mode;
+  if (pos_mode == VOIDmode)
+pos_mode = word_mode;
+
   insn->icode = icode;
-  insn->field_mode = mode;
-  insn->struct_mode = (type == ET_unaligned_mem ? BLKmode : mode);
-  insn->pos_mode = data->operand[pos_op].mode;
-  if (insn->pos_mode == VOIDmode)
-insn->pos_mode = word_mode;
+  insn->field_mode = as_a  (mode);
+  if (type == ET_unaligned_mem)
+insn->struct_mode = opt_scalar_int_mode ();
+  else
+insn->struct_mode = insn->field_mode;
+  insn->pos_mode = as_a  (pos_mode);
   return true;
 }
 
diff --git a/gcc/optabs-query.h b/gcc/optab

[41/67] Split scalar integer handling out of force_to_mode

2016-12-09 Thread Richard Sandiford
force_to_mode exits partway through for modes that aren't scalar
integers.  This patch splits the remainder of the function out
into a subroutine, force_int_to_mode, so that the modes from that
point on can have type scalar_int_mode.

The patch also makes sure that xmode is kept up-to-date with x
and uses xmode instead of GET_MODE (x) throughout.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* combine.c (force_int_to_mode): New function, split out from...
(force_to_here): ...here.  Keep xmode up-to-date and use it
instead of GET_MODE (x).

diff --git a/gcc/combine.c b/gcc/combine.c
index 449f371..0fcd428 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -446,6 +446,8 @@ static rtx extract_left_shift (rtx, int);
 static int get_pos_from_mask (unsigned HOST_WIDE_INT,
  unsigned HOST_WIDE_INT *);
 static rtx canon_reg_for_combine (rtx, rtx);
+static rtx force_int_to_mode (rtx, scalar_int_mode, scalar_int_mode,
+ scalar_int_mode, unsigned HOST_WIDE_INT, int);
 static rtx force_to_mode (rtx, machine_mode,
  unsigned HOST_WIDE_INT, int);
 static rtx if_then_else_cond (rtx, rtx *, rtx *);
@@ -8490,8 +8492,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned 
HOST_WIDE_INT mask,
   enum rtx_code code = GET_CODE (x);
   int next_select = just_select || code == XOR || code == NOT || code == NEG;
   machine_mode op_mode;
-  unsigned HOST_WIDE_INT fuller_mask, nonzero;
-  rtx op0, op1, temp;
+  unsigned HOST_WIDE_INT nonzero;
 
   /* If this is a CALL or ASM_OPERANDS, don't do anything.  Some of the
  code below will do the wrong thing since the mode of such an
@@ -8519,15 +8520,6 @@ force_to_mode (rtx x, machine_mode mode, unsigned 
HOST_WIDE_INT mask,
   if (op_mode)
 mask &= GET_MODE_MASK (op_mode);
 
-  /* When we have an arithmetic operation, or a shift whose count we
- do not know, we need to assume that all bits up to the highest-order
- bit in MASK will be needed.  This is how we form such a mask.  */
-  if (mask & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1)))
-fuller_mask = HOST_WIDE_INT_M1U;
-  else
-fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1))
-  - 1);
-
   /* Determine what bits of X are guaranteed to be (non)zero.  */
   nonzero = nonzero_bits (x, mode);
 
@@ -8565,9 +8557,42 @@ force_to_mode (rtx x, machine_mode mode, unsigned 
HOST_WIDE_INT mask,
& ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))
 return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
 
-  /* The arithmetic simplifications here only work for scalar integer modes.  
*/
-  if (!SCALAR_INT_MODE_P (mode) || !SCALAR_INT_MODE_P (GET_MODE (x)))
-return gen_lowpart_or_truncate (mode, x);
+  scalar_int_mode int_mode, xmode;
+  if (is_a  (mode, &int_mode)
+  && is_a  (GET_MODE (x), &xmode))
+/* OP_MODE is either MODE or XMODE, so it must be a scalar
+   integer too.  */
+return force_int_to_mode (x, int_mode, xmode,
+ as_a  (op_mode),
+ mask, just_select);
+
+  return gen_lowpart_or_truncate (mode, x);
+}
+
+/* Subroutine of force_to_mode that handles cases where both X and
+   the result are scalar integers.  MODE is the mode of the result,
+   XMODE is the mode of X, and OP_MODE says which of MODE or XMODE
+   is preferred for simplified versions of X.  The other arguments
+   are as for force_to_mode.  */
+
+static rtx
+force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode,
+  scalar_int_mode op_mode, unsigned HOST_WIDE_INT mask,
+  int just_select)
+{
+  enum rtx_code code = GET_CODE (x);
+  int next_select = just_select || code == XOR || code == NOT || code == NEG;
+  unsigned HOST_WIDE_INT fuller_mask;
+  rtx op0, op1, temp;
+
+  /* When we have an arithmetic operation, or a shift whose count we
+ do not know, we need to assume that all bits up to the highest-order
+ bit in MASK will be needed.  This is how we form such a mask.  */
+  if (mask & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1)))
+fuller_mask = HOST_WIDE_INT_M1U;
+  else
+fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1))
+  - 1);
 
   switch (code)
 {
@@ -8598,14 +8623,14 @@ force_to_mode (rtx x, machine_mode mode, unsigned 
HOST_WIDE_INT mask,
{
  x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
  mask & INTVAL (XEXP (x, 1)));
+ xmode = op_mode;
 
  /* If X is still an AND, see if it is an AND with a mask that
 is just some low-order bits.  If so, and it is MASK, we don't
 need it.  */
 
  if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))
- && ((INTVAL (XEXP (x, 1)) & GET_MODE_MASK (GET_MODE (x)))
- == mask))
+ && (IN

[42/67] Use scalar_int_mode in simplify_shift_const_1

2016-12-09 Thread Richard Sandiford
This patch makes simplify_shift_const_1 use scalar_int_modes
for all code that is specific to scalars rather than vectors.
This includes situations in which the new shift mode is different
from the original one, since the function never changes the mode
of vector shifts.  That in turn makes it more natural to test
for equal modes in simplify_shift_const_1 rather than
try_widen_shift_mode (which only applies to scalars).

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* combine.c (try_widen_shift_mode): Move check for equal modes to...
(simplify_shift_const_1): ...here.  Use scalar_int_mode for
shift_unit_mode and for modes involved in scalar shifts.

diff --git a/gcc/combine.c b/gcc/combine.c
index 0fcd428..3cb92a4 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -10296,8 +10296,6 @@ try_widen_shift_mode (enum rtx_code code, rtx op, int 
count,
  machine_mode orig_mode, machine_mode mode,
  enum rtx_code outer_code, HOST_WIDE_INT outer_const)
 {
-  if (orig_mode == mode)
-return mode;
   gcc_assert (GET_MODE_PRECISION (mode) > GET_MODE_PRECISION (orig_mode));
 
   /* In general we can't perform in wider mode for right shift and rotate.  */
@@ -10358,7 +10356,7 @@ simplify_shift_const_1 (enum rtx_code code, 
machine_mode result_mode,
   int count;
   machine_mode mode = result_mode;
   machine_mode shift_mode;
-  scalar_int_mode tmode, inner_mode;
+  scalar_int_mode tmode, inner_mode, int_mode, int_varop_mode, int_result_mode;
   unsigned int mode_words
 = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
   /* We form (outer_op (code varop count) (outer_const)).  */
@@ -10398,9 +10396,19 @@ simplify_shift_const_1 (enum rtx_code code, 
machine_mode result_mode,
  count = bitsize - count;
}
 
-  shift_mode = try_widen_shift_mode (code, varop, count, result_mode,
-mode, outer_op, outer_const);
-  machine_mode shift_unit_mode = GET_MODE_INNER (shift_mode);
+  shift_mode = result_mode;
+  if (shift_mode != mode)
+   {
+ /* We only change the modes of scalar shifts.  */
+ int_mode = as_a  (mode);
+ int_result_mode = as_a  (result_mode);
+ shift_mode = try_widen_shift_mode (code, varop, count,
+int_result_mode, int_mode,
+outer_op, outer_const);
+   }
+
+  scalar_int_mode shift_unit_mode
+   = as_a  (GET_MODE_INNER (shift_mode));
 
   /* Handle cases where the count is greater than the size of the mode
 minus 1.  For ASHIFT, use the size minus one as the count (this can
@@ -10495,6 +10503,7 @@ simplify_shift_const_1 (enum rtx_code code, 
machine_mode result_mode,
  /* The following rules apply only to scalars.  */
  if (shift_mode != shift_unit_mode)
break;
+ int_mode = as_a  (mode);
 
  /* If we have (xshiftrt (mem ...) C) and C is MODE_WIDTH
 minus the width of a smaller mode, we can do this with a
@@ -10503,15 +10512,15 @@ simplify_shift_const_1 (enum rtx_code code, 
machine_mode result_mode,
  && ! mode_dependent_address_p (XEXP (varop, 0),
 MEM_ADDR_SPACE (varop))
  && ! MEM_VOLATILE_P (varop)
- && (int_mode_for_size (GET_MODE_BITSIZE (mode) - count, 1)
+ && (int_mode_for_size (GET_MODE_BITSIZE (int_mode) - count, 1)
  .exists (&tmode)))
{
  new_rtx = adjust_address_nv (varop, tmode,
-  BYTES_BIG_ENDIAN ? 0
-  : count / BITS_PER_UNIT);
+  BYTES_BIG_ENDIAN ? 0
+  : count / BITS_PER_UNIT);
 
  varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
-: ZERO_EXTEND, mode, new_rtx);
+: ZERO_EXTEND, int_mode, new_rtx);
  count = 0;
  continue;
}
@@ -10521,20 +10530,22 @@ simplify_shift_const_1 (enum rtx_code code, 
machine_mode result_mode,
  /* The following rules apply only to scalars.  */
  if (shift_mode != shift_unit_mode)
break;
+ int_mode = as_a  (mode);
+ int_varop_mode = as_a  (GET_MODE (varop));
 
  /* If VAROP is a SUBREG, strip it as long as the inner operand has
 the same number of words as what we've seen so far.  Then store
 the widest mode in MODE.  */
  if (subreg_lowpart_p (varop)
  && is_int_mode (GET_MODE (SUBREG_REG (varop)), &inner_mode)
- && GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (GET_MODE (varop))
+ && GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (int_varop_mode)
   

[43/67] Use scalar_int_mode in simplify_comparison

2016-12-09 Thread Richard Sandiford
The main loop of simplify_comparison starts with:

  if (GET_MODE_CLASS (mode) != MODE_INT
  && ! (mode == VOIDmode
&& (GET_CODE (op0) == COMPARE || COMPARISON_P (op0
break;

So VOIDmode is only acceptable when comparing a COMPARE,
EQ, NE, etc. operand against a constant.  After this, the loop
calls simplify_compare_const to:

  (a) bring the constant op1 closer to 0 where possible and
  (b) use nonzero_bits and num_sign_bit_copies to get a simpler
  constant.

(a) works for both integer and VOID modes, (b) is specific
to integer modes.

The loop then has a big switch statement that handles further
simplifications.  This switch statement checks for COMPARISON_P
codes but not for COMPARE.

This patch uses scalar_int_mode to make the split between
(a) and (b) more explicit.  It also takes the COMPARISON_P
handling out of the switch statement and does it first,
so that the rest of the loop can treat the mode as a
scalar_int_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* combine.c (simplify_compare_const): Check that the mode is a
scalar_int_mode (rather than VOIDmode) before testing its
precision.
(simplify_comparison): Move COMPARISON_P handling out of the
loop and restrict the latter part of the loop to scalar_int_modes.
Check is_a  before call to HWI_COMPUTABLE_MODE_P
and when considering SUBREG_REGs.  Use is_int_mode instead of
checking GET_MODE_CLASS against MODE_INT.

diff --git a/gcc/combine.c b/gcc/combine.c
index 3cb92a4..58a8d7d 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -11608,7 +11608,7 @@ static enum rtx_code
 simplify_compare_const (enum rtx_code code, machine_mode mode,
rtx op0, rtx *pop1)
 {
-  unsigned int mode_width = GET_MODE_PRECISION (mode);
+  scalar_int_mode int_mode;
   HOST_WIDE_INT const_op = INTVAL (*pop1);
 
   /* Get the constant we are comparing against and turn off all bits
@@ -11623,10 +11623,11 @@ simplify_compare_const (enum rtx_code code, 
machine_mode mode,
   if (const_op
   && (code == EQ || code == NE || code == GE || code == GEU
  || code == LT || code == LTU)
-  && mode_width - 1 < HOST_BITS_PER_WIDE_INT
-  && pow2p_hwi (const_op & GET_MODE_MASK (mode))
-  && (nonzero_bits (op0, mode)
- == (unsigned HOST_WIDE_INT) (const_op & GET_MODE_MASK (mode
+  && is_a  (mode, &int_mode)
+  && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
+  && pow2p_hwi (const_op & GET_MODE_MASK (int_mode))
+  && (nonzero_bits (op0, int_mode)
+ == (unsigned HOST_WIDE_INT) (const_op & GET_MODE_MASK (int_mode
 {
   code = (code == EQ || code == GE || code == GEU ? NE : EQ);
   const_op = 0;
@@ -11637,7 +11638,8 @@ simplify_compare_const (enum rtx_code code, 
machine_mode mode,
   if (const_op == -1
   && (code == EQ || code == NE || code == GT || code == LE
  || code == GEU || code == LTU)
-  && num_sign_bit_copies (op0, mode) == mode_width)
+  && is_a  (mode, &int_mode)
+  && num_sign_bit_copies (op0, int_mode) == GET_MODE_PRECISION (int_mode))
 {
   code = (code == EQ || code == LE || code == GEU ? NE : EQ);
   const_op = 0;
@@ -11671,9 +11673,10 @@ simplify_compare_const (enum rtx_code code, 
machine_mode mode,
   /* If we are doing a <= 0 comparison on a value known to have
 a zero sign bit, we can replace this with == 0.  */
   else if (const_op == 0
-  && mode_width - 1 < HOST_BITS_PER_WIDE_INT
-  && (nonzero_bits (op0, mode)
-  & (HOST_WIDE_INT_1U << (mode_width - 1)))
+  && is_a  (mode, &int_mode)
+  && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
+  && (nonzero_bits (op0, int_mode)
+  & (HOST_WIDE_INT_1U << (GET_MODE_PRECISION (int_mode) - 1)))
   == 0)
code = EQ;
   break;
@@ -11701,9 +11704,10 @@ simplify_compare_const (enum rtx_code code, 
machine_mode mode,
   /* If we are doing a > 0 comparison on a value known to have
 a zero sign bit, we can replace this with != 0.  */
   else if (const_op == 0
-  && mode_width - 1 < HOST_BITS_PER_WIDE_INT
-  && (nonzero_bits (op0, mode)
-  & (HOST_WIDE_INT_1U << (mode_width - 1)))
+  && is_a  (mode, &int_mode)
+  && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
+  && (nonzero_bits (op0, int_mode)
+  & (HOST_WIDE_INT_1U << (GET_MODE_PRECISION (int_mode) - 1)))
   == 0)
code = NE;
   break;
@@ -11717,9 +11721,10 @@ simplify_compare_const (enum rtx_code code, 
machine_mode mode,
  /* ... fall through ...  */
}
   /* (unsigned) < 0x8000 is equivalent to >= 0.  */
-  else if (mode_width - 1 < HOST_BITS_PER_WIDE_INT
-   

[44/67] Make simplify_and_const_int take a scalar_int_mode

2016-12-09 Thread Richard Sandiford
After previous patches, top-level calls to simplify_and_const_int
always pass a scalar_int_mode.  The only call site that needs to
be updated is the recursive one in simplify_and_const_int_1,
at which point we know "varop" has a scalar integer mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* combine.c (simplify_and_const_int): Change the type of the mode
parameter to scalar_int_mode.
(simplify_and_const_int_1): Likewise.  Update recursive call.

diff --git a/gcc/combine.c b/gcc/combine.c
index 58a8d7d..5262bf9 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -456,9 +456,9 @@ static int rtx_equal_for_field_assignment_p (rtx, rtx, bool 
= false);
 static rtx make_field_assignment (rtx);
 static rtx apply_distributive_law (rtx);
 static rtx distribute_and_simplify_rtx (rtx, int);
-static rtx simplify_and_const_int_1 (machine_mode, rtx,
+static rtx simplify_and_const_int_1 (scalar_int_mode, rtx,
 unsigned HOST_WIDE_INT);
-static rtx simplify_and_const_int (rtx, machine_mode, rtx,
+static rtx simplify_and_const_int (rtx, scalar_int_mode, rtx,
   unsigned HOST_WIDE_INT);
 static int merge_outer_ops (enum rtx_code *, HOST_WIDE_INT *, enum rtx_code,
HOST_WIDE_INT, machine_mode, int *);
@@ -9880,7 +9880,7 @@ distribute_and_simplify_rtx (rtx x, int n)
(const_int CONSTOP)).  Otherwise, return NULL_RTX.  */
 
 static rtx
-simplify_and_const_int_1 (machine_mode mode, rtx varop,
+simplify_and_const_int_1 (scalar_int_mode mode, rtx varop,
  unsigned HOST_WIDE_INT constop)
 {
   unsigned HOST_WIDE_INT nonzero;
@@ -9940,19 +9940,20 @@ simplify_and_const_int_1 (machine_mode mode, rtx varop,
  won't match a pattern either with or without this.  */
 
   if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR)
-return
-  gen_lowpart
-   (mode,
-apply_distributive_law
-(simplify_gen_binary (GET_CODE (varop), GET_MODE (varop),
-  simplify_and_const_int (NULL_RTX,
-  GET_MODE (varop),
-  XEXP (varop, 0),
-  constop),
-  simplify_and_const_int (NULL_RTX,
-  GET_MODE (varop),
-  XEXP (varop, 1),
-  constop;
+{
+  scalar_int_mode varop_mode = as_a  (GET_MODE (varop));
+  return
+   gen_lowpart
+ (mode,
+  apply_distributive_law
+  (simplify_gen_binary (GET_CODE (varop), varop_mode,
+simplify_and_const_int (NULL_RTX, varop_mode,
+XEXP (varop, 0),
+constop),
+simplify_and_const_int (NULL_RTX, varop_mode,
+XEXP (varop, 1),
+constop;
+}
 
   /* If VAROP is PLUS, and the constant is a mask of low bits, distribute
  the AND and see if one of the operands simplifies to zero.  If so, we
@@ -9995,7 +9996,7 @@ simplify_and_const_int_1 (machine_mode mode, rtx varop,
X is zero, we are to always construct the equivalent form.  */
 
 static rtx
-simplify_and_const_int (rtx x, machine_mode mode, rtx varop,
+simplify_and_const_int (rtx x, scalar_int_mode mode, rtx varop,
unsigned HOST_WIDE_INT constop)
 {
   rtx tem = simplify_and_const_int_1 (mode, varop, constop);



Re: [24/67] Replace a != BLKmode check with is_a

2016-12-09 Thread Richard Biener
On Fri, Dec 9, 2016 at 2:08 PM, Richard Sandiford
 wrote:
> This patch replaces a check against BLKmode with a check
> of is_a , in a case where scalar integer
> modes were the only useful alternatives left.

So why's BLKmode no longer sth valid to check against?  The check is only there
to guard GET_MODE_ALIGNMENT / SLOW_UNALIGNED_ACCESS.

Richard.

> gcc/
> 2016-11-24  Richard Sandiford  
> Alan Hayward  
> David Sherwood  
>
> * gimple-fold.c (gimple_fold_builtin_memory_op): Use
> is_a  instead of != BLKmode.
>
> diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
> index d00625b..c6b5411 100644
> --- a/gcc/gimple-fold.c
> +++ b/gcc/gimple-fold.c
> @@ -713,31 +713,29 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator 
> *gsi,
>   unsigned ilen = tree_to_uhwi (len);
>   if (pow2p_hwi (ilen))
> {
> + scalar_int_mode mode;
>   tree type = lang_hooks.types.type_for_size (ilen * 8, 1);
>   if (type
> - && TYPE_MODE (type) != BLKmode
> - && (GET_MODE_SIZE (TYPE_MODE (type)) * BITS_PER_UNIT
> - == ilen * 8)
> + && is_a  (TYPE_MODE (type), &mode)
> + && GET_MODE_SIZE (mode) * BITS_PER_UNIT == ilen * 8
>   /* If the destination pointer is not aligned we must be able
>  to emit an unaligned store.  */
> - && (dest_align >= GET_MODE_ALIGNMENT (TYPE_MODE (type))
> - || !SLOW_UNALIGNED_ACCESS (TYPE_MODE (type), dest_align)
> - || (optab_handler (movmisalign_optab, TYPE_MODE (type))
> + && (dest_align >= GET_MODE_ALIGNMENT (mode)
> + || !SLOW_UNALIGNED_ACCESS (mode, dest_align)
> + || (optab_handler (movmisalign_optab, mode)
>   != CODE_FOR_nothing)))
> {
>   tree srctype = type;
>   tree desttype = type;
> - if (src_align < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
> + if (src_align < GET_MODE_ALIGNMENT (mode))
> srctype = build_aligned_type (type, src_align);
>   tree srcmem = fold_build2 (MEM_REF, srctype, src, off0);
>   tree tem = fold_const_aggregate_ref (srcmem);
>   if (tem)
> srcmem = tem;
> - else if (src_align < GET_MODE_ALIGNMENT (TYPE_MODE (type))
> -  && SLOW_UNALIGNED_ACCESS (TYPE_MODE (type),
> -src_align)
> -  && (optab_handler (movmisalign_optab,
> - TYPE_MODE (type))
> + else if (src_align < GET_MODE_ALIGNMENT (mode)
> +  && SLOW_UNALIGNED_ACCESS (mode, src_align)
> +  && (optab_handler (movmisalign_optab, mode)
>== CODE_FOR_nothing))
> srcmem = NULL_TREE;
>   if (srcmem)
> @@ -753,7 +751,7 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
>   gimple_set_vuse (new_stmt, gimple_vuse (stmt));
>   gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
> }
> - if (dest_align < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
> + if (dest_align < GET_MODE_ALIGNMENT (mode))
> desttype = build_aligned_type (type, dest_align);
>   new_stmt
> = gimple_build_assign (fold_build2 (MEM_REF, desttype,
>


Re: [Patch, Fortran, OOP] PR 61767: ICE in generate_finalization_wrapper at fortran/class.c:1491

2016-12-09 Thread Janus Weil
Hi Andre,

> yes, that was what I had in mind for the testcase. Now it looks ok to me.

thanks for reviewing, committed as r243483.

Cheers,
Janus



> On Thu, 8 Dec 2016 16:41:23 +0100
> Janus Weil  wrote:
>
>> Hi Andre,
>>
>> > so when I interpret the testcase correctly, than the finalizer should not 
>> > be
>> > called, right? So adding a call abort() in the Finalize and allocating and
>> > deallocating M in the main program should do no harm, but make the testcase
>> > IMO more feasible. What do you think?
>>
>> thanks for the comment. Indeed it can not hurt to extend it into a
>> runtime test. New version attached (according to your suggestions). Ok
>> with this?
>>
>> Cheers,
>> Janus
>>
>>
>>
>> > On Thu, 8 Dec 2016 13:56:29 +0100
>> > Janus Weil  wrote:
>> >
>> >> Hi all,
>> >>
>> >> the attached patch fixes an ice-on-valid problem with finalization.
>> >> The ICE turned out to be caused by a bug in 'has_finalizer_component':
>> >> According to the documentation, this function is supposed to detect
>> >> whether a derived type has any nonpointer nonallocatable components
>> >> that have a finalizer. However it triggered also on pointer components
>> >> with a finalizer. Fixing this makes the ICE go away.
>> >>
>> >> The patch regtests cleanly on x86_64-linux-gnu. Ok for trunk?
>> >>
>> >> Cheers,
>> >> Janus
>> >>
>> >>
>> >> 2016-12-08  Janus Weil  
>> >>
>> >> PR fortran/61767
>> >> * class.c (has_finalizer_component): Fix this function to detect only
>> >> non-pointer non-allocatable components which have a finalizer.
>> >>
>> >> 2016-12-08  Janus Weil  
>> >>
>> >> PR fortran/61767
>> >> * gfortran.dg/finalize_31.f90: New test.
>> >
>> >
>> > --
>> > Andre Vehreschild * Email: vehre ad gmx dot de
>
>
> --
> Andre Vehreschild * Email: vehre ad gmx dot de


[45/67] Make extract_left_shift take a scalar_int_mode

2016-12-09 Thread Richard Sandiford
This patch passes the mode of the shifted value to extract_left_shift
and updates the only caller so that the mode is a scalar_int_mode.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* combine.c (extract_left_shift): Add a mode argument and update
recursive calls.
(make_compound_operation_int): Change the type of the mode parameter
to scalar_int_mode and update the call to extract_left_shift.

diff --git a/gcc/combine.c b/gcc/combine.c
index 5262bf9..fac82d4 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -442,7 +442,6 @@ static rtx expand_compound_operation (rtx);
 static const_rtx expand_field_assignment (const_rtx);
 static rtx make_extraction (machine_mode, rtx, HOST_WIDE_INT,
rtx, unsigned HOST_WIDE_INT, int, int, int);
-static rtx extract_left_shift (rtx, int);
 static int get_pos_from_mask (unsigned HOST_WIDE_INT,
  unsigned HOST_WIDE_INT *);
 static rtx canon_reg_for_combine (rtx, rtx);
@@ -7778,14 +,14 @@ make_extraction (machine_mode mode, rtx inner, 
HOST_WIDE_INT pos,
   return new_rtx;
 }
 
-/* See if X contains an ASHIFT of COUNT or more bits that can be commuted
-   with any other operations in X.  Return X without that shift if so.  */
+/* See if X (of mode MODE) contains an ASHIFT of COUNT or more bits that
+   can be commuted with any other operations in X.  Return X without
+   that shift if so.  */
 
 static rtx
-extract_left_shift (rtx x, int count)
+extract_left_shift (scalar_int_mode mode, rtx x, int count)
 {
   enum rtx_code code = GET_CODE (x);
-  machine_mode mode = GET_MODE (x);
   rtx tem;
 
   switch (code)
@@ -7801,7 +7800,7 @@ extract_left_shift (rtx x, int count)
   break;
 
 case NEG:  case NOT:
-  if ((tem = extract_left_shift (XEXP (x, 0), count)) != 0)
+  if ((tem = extract_left_shift (mode, XEXP (x, 0), count)) != 0)
return simplify_gen_unary (code, mode, tem, mode);
 
   break;
@@ -7812,7 +7811,7 @@ extract_left_shift (rtx x, int count)
   if (CONST_INT_P (XEXP (x, 1))
  && (UINTVAL (XEXP (x, 1))
  & (((HOST_WIDE_INT_1U << count)) - 1)) == 0
- && (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
+ && (tem = extract_left_shift (mode, XEXP (x, 0), count)) != 0)
{
  HOST_WIDE_INT val = INTVAL (XEXP (x, 1)) >> count;
  return simplify_gen_binary (code, mode, tem,
@@ -7840,7 +7839,7 @@ extract_left_shift (rtx x, int count)
- Return a new rtx, which the caller returns directly.  */
 
 static rtx
-make_compound_operation_int (machine_mode mode, rtx *x_ptr,
+make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr,
 enum rtx_code in_code,
 enum rtx_code *next_code_ptr)
 {
@@ -8147,7 +8146,7 @@ make_compound_operation_int (machine_mode mode, rtx 
*x_ptr,
  && INTVAL (rhs) >= 0
  && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
  && INTVAL (rhs) < mode_width
- && (new_rtx = extract_left_shift (lhs, INTVAL (rhs))) != 0)
+ && (new_rtx = extract_left_shift (mode, lhs, INTVAL (rhs))) != 0)
new_rtx = make_extraction (mode, make_compound_operation (new_rtx, 
next_code),
   0, NULL_RTX, mode_width - INTVAL (rhs),
   code == LSHIFTRT, 0, in_code == COMPARE);



[46/67] Make widest_int_mode_for_size return a scalar_int_mode

2016-12-09 Thread Richard Sandiford
The comment for widest_int_mode said that it returns "the widest integer
mode no wider than SIZE", but it actually returns the widest integer
mode that is narrower than SIZE.  In practice SIZE is always greater
than 1, so it can always pick QImode in the worst case.  The VOIDmode
paths seem to be dead.

gcc/
2016-11-24  Richard Sandiford  
Alan Hayward  
David Sherwood  

* expr.c (widest_int_mode_for_size): Make the comment match the code.
Return a scalar_int_mode and assert that the size is greater than
one byte.
(by_pieces_ninsns): Update accordingly and remove VOIDmode handling.
(op_by_pieces_d::op_by_pieces_d): Likewise.
(op_by_pieces_d::run): Likewise.
(can_store_by_pieces): Likewise.

diff --git a/gcc/expr.c b/gcc/expr.c
index d54cc65..408a8bd 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -720,19 +720,21 @@ alignment_for_piecewise_move (unsigned int max_pieces, 
unsigned int align)
   return align;
 }
 
-/* Return the widest integer mode no wider than SIZE.  If no such mode
-   can be found, return VOIDmode.  */
+/* Return the widest integer mode that is narrower than SIZE bytes.  */
 
-static machine_mode
+static scalar_int_mode
 widest_int_mode_for_size (unsigned int size)
 {
-  machine_mode tmode, mode = VOIDmode;
+  scalar_int_mode result = NARROWEST_INT_MODE;
 
+  gcc_checking_assert (size > 1);
+
+  opt_scalar_int_mode tmode;
   FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
-if (GET_MODE_SIZE (tmode) < size)
-  mode = tmode;
+if (GET_MODE_SIZE (*tmode) < size)
+  result = *tmode;
 
-  return mode;
+  return result;
 }
 
 /* Determine whether an operation OP on LEN bytes with alignment ALIGN can
@@ -769,13 +771,9 @@ by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int 
align,
 
   while (max_size > 1 && l > 0)
 {
-  machine_mode mode;
+  scalar_int_mode mode = widest_int_mode_for_size (max_size);
   enum insn_code icode;
 
-  mode = widest_int_mode_for_size (max_size);
-
-  if (mode == VOIDmode)
-   break;
   unsigned int modesize = GET_MODE_SIZE (mode);
 
   icode = optab_handler (mov_optab, mode);
@@ -1051,7 +1049,7 @@ op_by_pieces_d::op_by_pieces_d (rtx to, bool to_load,
   if (by_pieces_ninsns (len, align, m_max_size, MOVE_BY_PIECES) > 2)
 {
   /* Find the mode of the largest comparison.  */
-  machine_mode mode = widest_int_mode_for_size (m_max_size);
+  scalar_int_mode mode = widest_int_mode_for_size (m_max_size);
 
   m_from.decide_autoinc (mode, m_reverse, len);
   m_to.decide_autoinc (mode, m_reverse, len);
@@ -1071,10 +1069,7 @@ op_by_pieces_d::run ()
 {
   while (m_max_size > 1 && m_len > 0)
 {
-  machine_mode mode = widest_int_mode_for_size (m_max_size);
-
-  if (mode == VOIDmode)
-   break;
+  scalar_int_mode mode = widest_int_mode_for_size (m_max_size);
 
   if (prepare_mode (mode, m_align))
{
@@ -1285,7 +1280,6 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
   unsigned HOST_WIDE_INT l;
   unsigned int max_size;
   HOST_WIDE_INT offset = 0;
-  machine_mode mode;
   enum insn_code icode;
   int reverse;
   /* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it.  */
@@ -1314,10 +1308,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
   max_size = STORE_MAX_PIECES + 1;
   while (max_size > 1 && l > 0)
{
- mode = widest_int_mode_for_size (max_size);
-
- if (mode == VOIDmode)
-   break;
+ scalar_int_mode mode = widest_int_mode_for_size (max_size);
 
  icode = optab_handler (mov_optab, mode);
  if (icode != CODE_FOR_nothing



  1   2   3   >