/* Gimple range edge functionaluity.
- Copyright (C) 2020 Free Software Foundation, Inc.
+ Copyright (C) 2020-2021 Free Software Foundation, Inc.
Contributed by Andrew MacLeod <amacleod@redhat.com>
and Aldy Hernandez <aldyh@redhat.com>.
}
-outgoing_range::outgoing_range ()
+// Return a TRUE or FALSE range representing the edge value of a GCOND.
+
+void
+gcond_edge_range (irange &r, edge e)
+{
+ gcc_checking_assert (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE));
+ if (e->flags & EDGE_TRUE_VALUE)
+ r = int_range<2> (boolean_true_node, boolean_true_node);
+ else
+ r = int_range<2> (boolean_false_node, boolean_false_node);
+}
+
+
+gimple_outgoing_range::gimple_outgoing_range ()
{
m_edge_table = NULL;
}
-outgoing_range::~outgoing_range ()
+
+gimple_outgoing_range::~gimple_outgoing_range ()
{
if (m_edge_table)
delete m_edge_table;
// Use a cached value if it exists, or calculate it if not.
bool
-outgoing_range::get_edge_range (irange &r, gimple *s, edge e)
+gimple_outgoing_range::get_edge_range (irange &r, gimple *s, edge e)
{
gcc_checking_assert (is_a<gswitch *> (s));
gswitch *sw = as_a<gswitch *> (s);
// Calculate all switch edges from SW and cache them in the hash table.
void
-outgoing_range::calc_switch_ranges (gswitch *sw)
+gimple_outgoing_range::calc_switch_ranges (gswitch *sw)
{
bool existed;
unsigned x, lim;
//
// Allocate an int_range_max for the default range case, start with
// varying and intersect each other case from it.
- irange *default_range = m_range_allocator.allocate (255);
- default_range->set_varying (type);
+ int_range_max default_range (type);
for (x = 1; x < lim; x++)
{
int_range_max def_range (low, high);
range_cast (def_range, type);
def_range.invert ();
- default_range->intersect (def_range);
+ default_range.intersect (def_range);
// Create/union this case with anything on else on the edge.
int_range_max case_range (low, high);
irange *&slot = m_edge_table->get_or_insert (default_edge, &existed);
// This should be the first call into this switch.
gcc_checking_assert (!existed);
- slot = default_range;
+ irange *dr = m_range_allocator.allocate (default_range);
+ slot = dr;
}
// return NULL
gimple *
-outgoing_range::edge_range_p (irange &r, edge e)
+gimple_outgoing_range::edge_range_p (irange &r, edge e)
{
// Determine if there is an outgoing edge.
gimple *s = gimple_outgoing_range_stmt_p (e->src);
if (is_a<gcond *> (s))
{
- if (e->flags & EDGE_TRUE_VALUE)
- r = int_range<2> (boolean_true_node, boolean_true_node);
- else if (e->flags & EDGE_FALSE_VALUE)
- r = int_range<2> (boolean_false_node, boolean_false_node);
- else
- gcc_unreachable ();
+ gcond_edge_range (r, e);
return s;
}