Re: fold() can't fold simple expressions?

2016-09-15 Thread Richard Biener
On Wed, Sep 14, 2016 at 9:49 PM, Jeff Law  wrote:
> On 09/14/2016 01:29 PM, Richard Biener wrote:
>
>>
>> It's what match-and-simplify does as well.
>>
>> I question the need to build GENERIC here though.  M-a-s happily gets you
>> a simplified expression as sequence of GIMPLE statements.  (But does not yet
>> provide a way to build a simplified GENERIC expression from GIMPLE IL)
>>
> At a particular site we're going to have an expression where we want to
> evaluate the operands (either to a constant or symbolically).
>
> For each operand in the expression we recursively raise the query "what is
> this operand".  THe result (potentially another expression) gets substituted
> in for the operand and the process continues recursively. Recursion stops
> when you get a constant or when you've walked back "too far" or the
> expression gets "too complex".
>
> Once you get something like (x+y)+z you're no longer gimple.  But we need to
> store that expression in some form.

I'm not sure you absolutely need to store it -- it is present in the
IL (in unoptimized
form) after all.

One reason current VRP symbolic ranges are "limited" is to avoid expensive stuff
such as folding (because of all the GC memory churn).  Yes -- if
something simplifies
to a constant we'd like to know, m-a-s lets you restrict results to constants
(so it avoids building up any larger expressions).  You also have a
lattice which
should contain any intermediate simplifications to constants.  You _may_ miss
some more advanced simplifications that require simplified
non-constant sub-"trees",
but folding never was able to catch all opportunities (think of
arbitrary associations
necessary to cancel everything to zero in a very large expression).  For some
areas in the compiler (IVO) we have the tree-affine stuff which has
its own mini-IL
capable of some more "advanced" simplifications (basically to catch
associations).

> That could be expressed as a vector of operators/operands.  It could be
> expressed as a generic tree.  Whatever.  Generic trees as a reasonably
> natural way to store the expression as its built, but fold() those arbitrary
> expressions doesn't work.  m-a-s may be the answer here, I haven't really
> thought about it yet.

The question is always full generality / complexity vs. working on a production
compiler where compile-time and memory use matter.  If you can create a
testcase, even if artificial, where we blow up worse than N log N this is bad.
[current VRP equivalences are such an example]

I believe that VRP for symbolic ranges is not terribly important besides
"simple" ranges like you can derive from a < b and c != d.

Oh, and if you are re-writing VRP range representation please get rid of
anti-ranges -- one "simple" extension of current VRP would get rid of
them by changing the current rep of a single range/anti-range to an
implicit union of two ranges (with that you can represent an anti-range).
Make the number of unioned ranges parametric and you end up with
sth quite general.

And symbolic ranges should be IMHO represented by maintaining
a set of active true/false predicates rather than trying to come up
with a "range" representation.  And for predicates we'd like to have
a mini-IL like tree-affine -- this would be generally useful elsewhere
in the compiler as well.

Richard.


Re: fold() can't fold simple expressions?

2016-09-15 Thread Jeff Law

On 09/15/2016 02:06 AM, Richard Biener wrote:

On Wed, Sep 14, 2016 at 9:49 PM, Jeff Law  wrote:

On 09/14/2016 01:29 PM, Richard Biener wrote:



It's what match-and-simplify does as well.

I question the need to build GENERIC here though.  M-a-s happily
gets you a simplified expression as sequence of GIMPLE
statements.  (But does not yet provide a way to build a
simplified GENERIC expression from GIMPLE IL)


At a particular site we're going to have an expression where we
want to evaluate the operands (either to a constant or
symbolically).

For each operand in the expression we recursively raise the query
"what is this operand".  THe result (potentially another
expression) gets substituted in for the operand and the process
continues recursively. Recursion stops when you get a constant or
when you've walked back "too far" or the expression gets "too
complex".

Once you get something like (x+y)+z you're no longer gimple.  But
we need to store that expression in some form.


I'm not sure you absolutely need to store it -- it is present in the
IL (in unoptimized form) after all.
But we don't want to change the IL :-)  We want to analyze the IL to 
determine properties of SSA_NAMEs on various paths through the CFG.


The current scheme of mapping range data to an SSA_NAME was an 
improvement and that range data is starting to be used in various places 
in the compiler.   But that scheme loses extremely valuable data that 
warnings can and should be using.


We typically have ASSERT_EXPRs at branch points in the CFG.  The 
ASSERT_EXPRs carry range information for a path.  However we do not 
consider an ASSERT_EXPR a true copy.  ie, after the merge point of the 
paths uses continue to refer to the original object (the RHS of the 
ASSERT_EXPRs).


Thus after VRP most of the path sensitive data is dropped on the floor.

Aldy explored making ASSERT_EXPRs true copies.  It's a simple change to 
make and certainly gets PHIs at the merge point.  So it seems like a 
good start.


The downside is there's a significant compile-time cost (via update_ssa) 
to this scheme.  Furthermore, we believe that we only need path specific 
data for a subset of the SSA_NAMEs used in conditionals.  So much of the 
time is wasted computing information we don't actually need.


Worse yet, copy-prop takes the copy created by the ASSERT_EXPR, 
propagates it to the RHS of the PHI and the PHI ends up as a degenerate 
and gets removed -- at which point we've lost the path specific range 
data again.  Ugh.


If we tell copy-prop not to propagate those copies until we're done with 
the range data we run the real risk of making code worse and it's just a 
gross hack, similar how we have to test if an SSA_NAME is used in an 
abnormal PHI hack.


So the scheme we're exploring now is an on-demand generation of path 
specific range data using back substitution.  It's primarily Andrew's 
ideas, but just happens to mirror parts of the predicate analysis one 
finds in tree-ssa-uninit.c and my thoughts on how we should be 
finding/exploiting path specific equivalences for threading and CSE.






That could be expressed as a vector of operators/operands.  It
could be expressed as a generic tree.  Whatever.  Generic trees as
a reasonably natural way to store the expression as its built, but
fold() those arbitrary expressions doesn't work.  m-a-s may be the
answer here, I haven't really thought about it yet.


The question is always full generality / complexity vs. working on a
production compiler where compile-time and memory use matter.  If you
can create a testcase, even if artificial, where we blow up worse
than N log N this is bad. [current VRP equivalences are such an
example]

Absolutely.


Oh, and if you are re-writing VRP range representation please get rid
of anti-ranges -- one "simple" extension of current VRP would get rid
of them by changing the current rep of a single range/anti-range to
an implicit union of two ranges (with that you can represent an
anti-range). Make the number of unioned ranges parametric and you end
up with sth quite general.
Andrew's scheme (among other things) is designed to give us that 
flexibility.  One of the things we want to explore is how many ranges we 
really need in practice.  It's at least 2 (so we can support 
anti-ranges), but we don't have a sense of how useful > 2 is in practice.




And symbolic ranges should be IMHO represented by maintaining a set
of active true/false predicates rather than trying to come up with a
"range" representation.  And for predicates we'd like to have a
mini-IL like tree-affine -- this would be generally useful elsewhere
in the compiler as well.
That would be possible as well -- essentially it's a representational 
issue.  If you look in tree-ssa-uninit.c you'll see something like this. 
 I'm still looking for an victim to rip tree-ssa-uninit.c apart so that 
its predicate analysis can be used in other places.


jeff


Re: fold() can't fold simple expressions?

2016-09-15 Thread Richard Biener
On September 15, 2016 6:21:34 PM GMT+02:00, Jeff Law  wrote:
>On 09/15/2016 02:06 AM, Richard Biener wrote:
>> On Wed, Sep 14, 2016 at 9:49 PM, Jeff Law  wrote:
>>> On 09/14/2016 01:29 PM, Richard Biener wrote:
>>>

 It's what match-and-simplify does as well.

 I question the need to build GENERIC here though.  M-a-s happily
 gets you a simplified expression as sequence of GIMPLE
 statements.  (But does not yet provide a way to build a
 simplified GENERIC expression from GIMPLE IL)

>>> At a particular site we're going to have an expression where we
>>> want to evaluate the operands (either to a constant or
>>> symbolically).
>>>
>>> For each operand in the expression we recursively raise the query
>>> "what is this operand".  THe result (potentially another
>>> expression) gets substituted in for the operand and the process
>>> continues recursively. Recursion stops when you get a constant or
>>> when you've walked back "too far" or the expression gets "too
>>> complex".
>>>
>>> Once you get something like (x+y)+z you're no longer gimple.  But
>>> we need to store that expression in some form.
>>
>> I'm not sure you absolutely need to store it -- it is present in the
>> IL (in unoptimized form) after all.
>But we don't want to change the IL :-)  We want to analyze the IL to 
>determine properties of SSA_NAMEs on various paths through the CFG.

You don't change the IL but only the lattice used to valueize the SSA names 
when you walk the IL 'looking up' the optimized expression.

Richard.

>The current scheme of mapping range data to an SSA_NAME was an 
>improvement and that range data is starting to be used in various
>places 
>in the compiler.   But that scheme loses extremely valuable data that 
>warnings can and should be using.
>
>We typically have ASSERT_EXPRs at branch points in the CFG.  The 
>ASSERT_EXPRs carry range information for a path.  However we do not 
>consider an ASSERT_EXPR a true copy.  ie, after the merge point of the 
>paths uses continue to refer to the original object (the RHS of the 
>ASSERT_EXPRs).
>
>Thus after VRP most of the path sensitive data is dropped on the floor.
>
>Aldy explored making ASSERT_EXPRs true copies.  It's a simple change to
>
>make and certainly gets PHIs at the merge point.  So it seems like a 
>good start.
>
>The downside is there's a significant compile-time cost (via
>update_ssa) 
>to this scheme.  Furthermore, we believe that we only need path
>specific 
>data for a subset of the SSA_NAMEs used in conditionals.  So much of
>the 
>time is wasted computing information we don't actually need.
>
>Worse yet, copy-prop takes the copy created by the ASSERT_EXPR, 
>propagates it to the RHS of the PHI and the PHI ends up as a degenerate
>
>and gets removed -- at which point we've lost the path specific range 
>data again.  Ugh.
>
>If we tell copy-prop not to propagate those copies until we're done
>with 
>the range data we run the real risk of making code worse and it's just
>a 
>gross hack, similar how we have to test if an SSA_NAME is used in an 
>abnormal PHI hack.
>
>So the scheme we're exploring now is an on-demand generation of path 
>specific range data using back substitution.  It's primarily Andrew's 
>ideas, but just happens to mirror parts of the predicate analysis one 
>finds in tree-ssa-uninit.c and my thoughts on how we should be 
>finding/exploiting path specific equivalences for threading and CSE.
>
>
>>
>>> That could be expressed as a vector of operators/operands.  It
>>> could be expressed as a generic tree.  Whatever.  Generic trees as
>>> a reasonably natural way to store the expression as its built, but
>>> fold() those arbitrary expressions doesn't work.  m-a-s may be the
>>> answer here, I haven't really thought about it yet.
>>
>> The question is always full generality / complexity vs. working on a
>> production compiler where compile-time and memory use matter.  If you
>> can create a testcase, even if artificial, where we blow up worse
>> than N log N this is bad. [current VRP equivalences are such an
>> example]
>Absolutely.
>
>> Oh, and if you are re-writing VRP range representation please get rid
>> of anti-ranges -- one "simple" extension of current VRP would get rid
>> of them by changing the current rep of a single range/anti-range to
>> an implicit union of two ranges (with that you can represent an
>> anti-range). Make the number of unioned ranges parametric and you end
>> up with sth quite general.
>Andrew's scheme (among other things) is designed to give us that 
>flexibility.  One of the things we want to explore is how many ranges
>we 
>really need in practice.  It's at least 2 (so we can support 
>anti-ranges), but we don't have a sense of how useful > 2 is in
>practice.
>
>>
>> And symbolic ranges should be IMHO represented by maintaining a set
>> of active true/false predicates rather than trying to come up with a
>> "range" representation.  And for predicates we'd like to have a
>> mini-I

Message missing from gcc-patches

2016-09-15 Thread Bernd Edlinger
Hi,

this message did not get listed on the gcc-patches archive.
I've got no bounce, and it just vanished, several times.

Any idea what is wrong?


Bernd.


 Forwarded Message 
Subject: [PATCHv3, resent] Add a warning for suspicious use of 
conditional expressions in boolean context
Date: Thu, 15 Sep 2016 11:19:32 +0200
From: Bernd Edlinger 
To: GCC Patches 
CC: Jason Merrill , Jeff Law , Joseph 
Myers 

Hi,

I send the latest version of the warning patch again, because I don't
see the previous patch submission on the gcc-patches list.  It dropped
out silently, twice :(

Don't know what went wrong, so please excuse me if this e-mail arrives
duplicate.


On 09/14/16 20:11, Jason Merrill wrote:
>>
>> Yes.  The reasoning I initially had was that it is completely
>> pointless to have something of the form "if (x ? 1 : 2)" or
>> "if (x ? 0 : 0)" because the result does not even depend on x
>> in this case.  But something like "if (x ? 4999 : 0)" looks
>> bogus but does at least not ignore x.
>>
>> If the false-positives are becoming too much of a problem here,
>> then I should of course revert to the previous heuristic again.
>
> I think we could have both, where the weaker form is part of -Wall and
> people can explicitly select the stronger form.
>


Yes, agreed.  So here is what I would think will be the first version.

It can later be extended to cover the more pedantic cases which
will not be enabled by -Wall.

I would like to send a follow-up patch for the warning on
signed-integer shift left in boolean context, which I think
should also be good for Wall.
(I already had that feature in patch version 2 but that's meanwhile
outdated).


Bootstrap and reg-testing on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.


gcc:
2016-09-14  Bernd Edlinger  

PR c++/77434
* doc/invoke.texi: Document -Wcond-in-bool-context.

PR middle-end/77421
* dwarf2out.c (output_loc_operands): Fix an assertion.

c-family:
2016-09-14  Bernd Edlinger  

PR c++/77434
* c.opt (Wcond-in-bool-context): New warning.
* c-common.c (c_common_truthvalue_conversion): Warn on integer
constants in boolean context.

cp:
2016-09-14  Bernd Edlinger  

PR c++/77434
* cvt.c (cp_convert_and_check): Suppress Wint-in-bool-context here.

testsuite:
2016-09-14  Bernd Edlinger  

PR c++/77434
* c-c++-common/Wcond-in-bool-context.c: New test.
Index: gcc/builtins.c
===
--- gcc/builtins.c	(revision 240135)
+++ gcc/builtins.c	(working copy)
@@ -7887,15 +7887,18 @@ fold_builtin_classify (location_t loc, tree fndecl
 	tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
 
 	signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
-	signbit_call, integer_zero_node);
+	signbit_call, integer_zero_node);
 	isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
-  isinf_call, integer_zero_node);
+	  isinf_call, integer_zero_node);
 
-	tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
-			   integer_minus_one_node, integer_one_node);
 	tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
-			   isinf_call, tmp,
-			   integer_zero_node);
+   signbit_call, integer_minus_one_node,
+   integer_one_node);
+	/* Avoid a possible -Wint-in-bool-context warning in C.  */
+	tmp = fold_build2_loc (loc, PLUS_EXPR, integer_type_node, tmp,
+   integer_zero_node);
+	tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
+   isinf_call, tmp, integer_zero_node);
 	  }
 
 	return tmp;
Index: gcc/c-family/c-common.c
===
--- gcc/c-family/c-common.c	(revision 240135)
+++ gcc/c-family/c-common.c	(working copy)
@@ -4652,6 +4652,19 @@ c_common_truthvalue_conversion (location_t locatio
 	   TREE_OPERAND (expr, 0));
 
 case COND_EXPR:
+  if (warn_int_in_bool_context)
+	{
+	  tree val1 = fold_for_warn (TREE_OPERAND (expr, 1));
+	  tree val2 = fold_for_warn (TREE_OPERAND (expr, 2));
+	  if (TREE_CODE (val1) == INTEGER_CST
+	  && TREE_CODE (val2) == INTEGER_CST
+	  && !integer_zerop (val1)
+	  && !integer_zerop (val2)
+	  && (!integer_onep (val1)
+		  || !integer_onep (val2)))
+	warning_at (EXPR_LOCATION (expr), OPT_Wint_in_bool_context,
+		"?: using integer constants in boolean context");
+	}
   /* Distribute the conversion into the arms of a COND_EXPR.  */
   if (c_dialect_cxx ())
 	{
Index: gcc/c-family/c.opt
===
--- gcc/c-family/c.opt	(revision 240135)
+++ gcc/c-family/c.opt	(working copy)
@@ -545,6 +545,10 @@ Wint-conversion
 C ObjC Var(warn_int_conversion) Init(1) Warning
 Warn about incompatible integer to pointer and pointer to integer conversions.
 
+Wint-in-bool-context
+C ObjC C++ ObjC++ V

Re: Message missing from gcc-patches

2016-09-15 Thread Jeff Law

On 09/15/2016 11:12 AM, Bernd Edlinger wrote:

Hi,

this message did not get listed on the gcc-patches archive.
I've got no bounce, and it just vanished, several times.

Any idea what is wrong?
No clue.  It's not likely hitting the maximum size limits.  And I 
certainly got the copy addressed directly to me.


Jeff



gcc-6-20160915 is now available

2016-09-15 Thread gccadmin
Snapshot gcc-6-20160915 is now available on
  ftp://gcc.gnu.org/pub/gcc/snapshots/6-20160915/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 6 SVN branch
with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-6-branch 
revision 240167

You'll find:

 gcc-6-20160915.tar.bz2   Complete GCC

  MD5=23b41bfd11226dbb7b5017e6d73f8fe1
  SHA1=0fb6a9f938e7a566ee232c121e917e78a45587df

Diffs from 6-20160908 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-6
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.