aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-range.cc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2022-06-01 16:58:36 +0200
committerAldy Hernandez <aldyh@redhat.com>2022-06-03 10:31:01 +0200
commit89b0276d3fafdd254e17beee3c86ec00edcf28a2 (patch)
tree5fcc6c8fd7dbae658f1376faae0ce1bbd7140f14 /gcc/value-range.cc
parenta9058b08381cd76e8d21364f0f5ccddb3777c3fd (diff)
downloadgcc-89b0276d3fafdd254e17beee3c86ec00edcf28a2.zip
gcc-89b0276d3fafdd254e17beee3c86ec00edcf28a2.tar.gz
gcc-89b0276d3fafdd254e17beee3c86ec00edcf28a2.tar.bz2
Flesh out unsupported_range.
It's cleaner to have the unsupported_range fully fleshed out, instead of trapping on every operation. It can also serve as the basis for the default vrange methods that frange and prange will inherit. This patch implements most methods, including union and intersect, to handle an UNDEFINED and a VARYING range. Since this can serve as the basis for other classes, I have moved everything into the vrange class, making the unsupported_range trivial. Note that vrange is still an abstract class, as I have purposely left the dump() method abstract. Also, I have made the unsupported range in the temporary class (Value_Range) a method field, instead of a static member. This way the temporary can set UNDEFINED and VARYING as needed. Tested on x86-64 Linux. gcc/ChangeLog: * value-range.cc (vrange::contains_p): Implement. (vrange::type): Return void. (vrange::supports_type_p): Implement. (irange::fits_p): Same. (vrange::set_undefined): Same. (irange::set_nonnegative): Same. (vrange::set_varying): Same. (vrange::union_): Same. (unsupported_range::set): Move to vrange. (unsupported_range::type): Move to vrange. (vrange::intersect): Implement for varying and undefined. (vrange::zero_p): Implement. (unsupported_range::supports_type_p): Move to vrange. (vrange::nonzero_p): Implement. (unsupported_range::set_undefined): Move to vrange. (unsupported_range::set_varying): Same. (unsupported_range::dump): Same. (unsupported_range::union_): Same. Implement for varying and undefined. (unsupported_range::intersect): Move to vrange. (unsupported_range::zero_p): Same. (unsupported_range::nonzero_p): Same. (unsupported_range::set_nonzero): Same. (unsupported_range::set_zero): Same. (unsupported_range::set_nonnegative): Same. (unsupported_range::fits_p): Same. * value-range.h (class vrange): Remove abstract markers for most methods. (class unsupported_range): Remove most methods as they will now be inherited from vrange.
Diffstat (limited to 'gcc/value-range.cc')
-rw-r--r--gcc/value-range.cc175
1 files changed, 91 insertions, 84 deletions
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index c4bcb97..815cb78 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -66,176 +66,183 @@ debug (const Value_Range &r)
fprintf (stderr, "\n");
}
-// Default implementation when none has been defined.
+// Default vrange definitions.
bool
vrange::contains_p (tree) const
{
- return false;
+ return varying_p ();
}
-// Default implementation when none has been defined.
-
bool
vrange::singleton_p (tree *) const
{
return false;
}
-// Assignment operator for generic ranges. Copying incompatible types
-// is not allowed.
-
-vrange &
-vrange::operator= (const vrange &src)
+void
+vrange::set (tree, tree, value_range_kind)
{
- if (is_a <irange> (src))
- {
- as_a <irange> (*this) = as_a <irange> (src);
- return *this;
- }
- else
- gcc_unreachable ();
}
-// Equality operator for generic ranges.
-
-bool
-vrange::operator== (const vrange &src) const
+tree
+vrange::type () const
{
- if (is_a <irange> (src))
- return as_a <irange> (*this) == as_a <irange> (src);
- gcc_unreachable ();
+ return void_type_node;
}
bool
-irange::supports_type_p (tree type) const
+vrange::supports_type_p (tree) const
{
- return supports_p (type);
+ return false;
}
-// Return TRUE if R fits in THIS.
-
-bool
-irange::fits_p (const vrange &r) const
+void
+vrange::set_undefined ()
{
- return m_max_ranges >= as_a <irange> (r).num_pairs ();
+ m_kind = VR_UNDEFINED;
}
void
-irange::set_nonnegative (tree type)
+vrange::set_varying (tree)
{
- set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
+ m_kind = VR_VARYING;
}
-unsupported_range::unsupported_range ()
+bool
+vrange::union_ (const vrange &r)
{
- m_discriminator = VR_UNKNOWN;
- set_undefined ();
+ if (r.undefined_p () || varying_p ())
+ return false;
+ if (undefined_p () || r.varying_p ())
+ {
+ operator= (r);
+ return true;
+ }
+ gcc_unreachable ();
+ return false;
}
-void
-unsupported_range::set (tree, tree, value_range_kind)
+bool
+vrange::intersect (const vrange &r)
{
+ if (undefined_p () || r.varying_p ())
+ return false;
+ if (r.undefined_p ())
+ {
+ set_undefined ();
+ return true;
+ }
+ if (varying_p ())
+ {
+ operator= (r);
+ return true;
+ }
gcc_unreachable ();
+ return false;
}
-tree
-unsupported_range::type () const
+bool
+vrange::zero_p () const
{
- gcc_unreachable ();
- return nullptr;
+ return false;
}
bool
-unsupported_range::supports_type_p (tree) const
+vrange::nonzero_p () const
{
return false;
}
void
-unsupported_range::set_undefined ()
+vrange::set_nonzero (tree)
{
- m_kind = VR_UNDEFINED;
}
void
-unsupported_range::set_varying (tree)
+vrange::set_zero (tree)
{
- gcc_unreachable ();
}
void
-unsupported_range::dump (FILE *file) const
+vrange::set_nonnegative (tree)
{
- fprintf (file, "[unsupported_range] ");
- if (undefined_p ())
- {
- fprintf (file, "UNDEFINED");
- return;
- }
- if (varying_p ())
- {
- fprintf (file, "VARYING");
- return;
- }
- gcc_unreachable ();
}
bool
-unsupported_range::union_ (const vrange &)
+vrange::fits_p (const vrange &) const
{
- gcc_unreachable ();
- return false;
+ return true;
}
-bool
-unsupported_range::intersect (const vrange &)
+// Assignment operator for generic ranges. Copying incompatible types
+// is not allowed.
+
+vrange &
+vrange::operator= (const vrange &src)
{
- gcc_unreachable ();
- return false;
+ if (is_a <irange> (src))
+ {
+ as_a <irange> (*this) = as_a <irange> (src);
+ return *this;
+ }
+ else
+ gcc_unreachable ();
}
+// Equality operator for generic ranges.
+
bool
-unsupported_range::zero_p () const
+vrange::operator== (const vrange &src) const
{
+ if (is_a <irange> (src))
+ return as_a <irange> (*this) == as_a <irange> (src);
gcc_unreachable ();
- return false;
}
bool
-unsupported_range::nonzero_p () const
+irange::supports_type_p (tree type) const
{
- gcc_unreachable ();
- return false;
+ return supports_p (type);
}
-void
-unsupported_range::set_nonzero (tree)
+// Return TRUE if R fits in THIS.
+
+bool
+irange::fits_p (const vrange &r) const
{
- gcc_unreachable ();
+ return m_max_ranges >= as_a <irange> (r).num_pairs ();
}
void
-unsupported_range::set_zero (tree)
+irange::set_nonnegative (tree type)
{
- gcc_unreachable ();
+ set (build_int_cst (type, 0), TYPE_MAX_VALUE (type));
}
-void
-unsupported_range::set_nonnegative (tree)
+unsupported_range::unsupported_range ()
{
- gcc_unreachable ();
+ m_discriminator = VR_UNKNOWN;
+ set_undefined ();
}
-bool
-unsupported_range::fits_p (const vrange &) const
+void
+unsupported_range::dump (FILE *file) const
{
+ fprintf (file, "[unsupported_range] ");
+ if (undefined_p ())
+ {
+ fprintf (file, "UNDEFINED");
+ return;
+ }
+ if (varying_p ())
+ {
+ fprintf (file, "VARYING");
+ return;
+ }
gcc_unreachable ();
- return false;
}
-unsupported_range Value_Range::m_unsupported;
-
// Here we copy between any two irange's. The ranges can be legacy or
// multi-ranges, and copying between any combination works correctly.