[PATCH 2/6] gimple-range-edge

2020-10-02 Thread Andrew MacLeod via Gcc-patches
This file produces constant edge ranges.  It provides a class which can 
be instantiated and will return the range on any edge.


This was originally suppose to be trivial, but switches mucked that up :-)

There are 2 basic expressions that can result ina  constant range on an 
edge:
Note there is nothing related to ssa or anythin else, its about ranges 
which are forced by the edge.


a gimple condition:

BB2:
    if (_3 != 0)
  goto ; [INV]
    else
  goto ; [INV]

a query for range on edge 2->3 returns [1,1]  (TRUE)
a query for range on edge 2->5 returns [0,0] (FALSE)

the other case, and the reason this exists, is for switches.  There is 
no simple way to map the values on switch edges implied by the labels 
without walking through the switch statement and calculating them.  The 
on-demand ranger was spending a lot of time recalculating these values 
for multiple requests, thus this class was created to process a switch 
once, and cache the values.


y = x + 4
switch (x)
 {
 case 0:
 case 1:
 return 1;
 case 2:
 return y;
 case 3:
 case 10:
 return 3;
 default:
    return x;
 }

Any request for the range on any edge leaving the switch will calculate 
all the edge ranges at once and cache them.  subsequent queries will 
then just return the cached value.


 :
 switch (x_2(D))  [INV], case 0 ... 1:  [INV], 
case 2:  [INV], case 3:  [INV], case 10:  [INV]>


4->7  x_2(D) :  unsigned int [4, 9][11, +INF] // default 
edge

4->8  x_2(D) :  unsigned int [0, 1]
4->5  x_2(D) :  unsigned int [2, 2]
4->6  x_2(D) :  unsigned int [3, 3][10, 10]

There is no ranger dependency, this can be used on any valid gimple IL 
to get the ranges implied by the edge.


The ranger is needed to map those values to the switch variable, and 
also apply any previous ranges or derived values (ie, if you ask for the 
range of 'y' in case 2, it will return unsigned int [6,6].

	* gimple-range-edge.h: New File.
	(outgoing_range): Calculate/cache constant outgoing edge ranges.

	* gimple-range-edge.cc: New file.
	(gimple_outgoing_range_stmt_p): New.  Find control statement.
	(outgoing_range::outgoing_range): New.
	(outgoing_range::~outgoing_range): New.
	(outgoing_range::get_edge_range): New.  Internal switch edge query.
	(outgoing_range::calc_switch_ranges): New.  Calculate switch ranges.
	(outgoing_range::edge_range_p): New.  Find constant range on edge.

diff --git a/gcc/gimple-range-edge.h b/gcc/gimple-range-edge.h
new file mode 100644
index 000..400c814ac7e
--- /dev/null
+++ b/gcc/gimple-range-edge.h
@@ -0,0 +1,55 @@
+/* Gimple range edge header file.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Andrew MacLeod 
+   and Aldy Hernandez .
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#ifndef GIMPLE_RANGE_EDGE_H
+#define GIMPLE_RANGE_EDGE_H
+
+// This class is used to query ranges on constant edges in GIMPLE.
+//
+// For a COND_EXPR, the TRUE edge will return [1,1] and the false edge a [0,0].
+//
+// For SWITCH_EXPR, it is awkward to calculate ranges.  When a request
+// is made, the entire switch is evalauted and the results cached. 
+// Any future requests to that switch will use the cached value, providing
+// dramatic decrease in computation time.
+//
+// The API is simple, just ask for the range on the edge.
+// The return value is NULL for no range, or the branch statement which the
+// edge gets the range from, along with the range.
+
+class outgoing_range
+{
+public:
+  outgoing_range ();
+  ~outgoing_range ();
+  gimple *edge_range_p (irange &r, edge e);
+private:
+  void calc_switch_ranges (gswitch *sw);
+  bool get_edge_range (irange &r, gimple *s, edge e);
+
+  hash_map *m_edge_table;
+  irange_allocator m_range_allocator;
+}; 
+
+// If there is a range control statment at the end of block BB, return it.
+gimple *gimple_outgoing_range_stmt_p (basic_block bb);
+
+#endif  // GIMPLE_RANGE_EDGE_H
diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
new file mode 100644
index 000..c5ee54fec51
--- /dev/null
+++ b/gcc/gimple-range-edge.cc
@@ -0,0 +1,197 @@
+/* Gimple range edge functionaluity.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Andrew MacLeod 
+   and Aldy Hernandez .
+
+This file is part of GCC.
+
+GCC is free s

Re: [PATCH 2/6] gimple-range-edge

2020-10-05 Thread Jakub Jelinek via Gcc-patches
On Fri, Oct 02, 2020 at 12:59:54PM -0400, Andrew MacLeod via Gcc-patches wrote:
> 
> The ranger is needed to map those values to the switch variable, and also
> apply any previous ranges or derived values (ie, if you ask for the range of
> 'y' in case 2, it will return unsigned int [6,6].

> 
>   * gimple-range-edge.h: New File.
>   (outgoing_range): Calculate/cache constant outgoing edge ranges.
> 
>   * gimple-range-edge.cc: New file.
>   (gimple_outgoing_range_stmt_p): New.  Find control statement.
>   (outgoing_range::outgoing_range): New.
>   (outgoing_range::~outgoing_range): New.
>   (outgoing_range::get_edge_range): New.  Internal switch edge query.
>   (outgoing_range::calc_switch_ranges): New.  Calculate switch ranges.
>   (outgoing_range::edge_range_p): New.  Find constant range on edge.

Just a ChangeLog comment (ditto for several other patches).
When you add a new file, just say that and nothing else, i.e.
* gimple-range-edge.h: New File.
* gimple-range-edge.cc: New file.
and that's it.  Everything in the new file is new, no need to state it
explicitly.

Jakub



Re: [PATCH 2/6] gimple-range-edge

2020-10-05 Thread Andrew MacLeod via Gcc-patches

On 10/5/20 8:09 AM, Jakub Jelinek wrote:

On Fri, Oct 02, 2020 at 12:59:54PM -0400, Andrew MacLeod via Gcc-patches wrote:

The ranger is needed to map those values to the switch variable, and also
apply any previous ranges or derived values (ie, if you ask for the range of
'y' in case 2, it will return unsigned int [6,6].
* gimple-range-edge.h: New File.
(outgoing_range): Calculate/cache constant outgoing edge ranges.

* gimple-range-edge.cc: New file.
(gimple_outgoing_range_stmt_p): New.  Find control statement.
(outgoing_range::outgoing_range): New.
(outgoing_range::~outgoing_range): New.
(outgoing_range::get_edge_range): New.  Internal switch edge query.
(outgoing_range::calc_switch_ranges): New.  Calculate switch ranges.
(outgoing_range::edge_range_p): New.  Find constant range on edge.

Just a ChangeLog comment (ditto for several other patches).
When you add a new file, just say that and nothing else, i.e.
* gimple-range-edge.h: New File.
* gimple-range-edge.cc: New file.
and that's it.  Everything in the new file is new, no need to state it
explicitly.

Jakub
Really? huh. ok.  Figured it was useful for anyone looking up a routine 
name. That will dramatically shrink these changelogs :-)


Andrew