diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2022-07-24 19:42:11 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2022-07-25 08:45:21 +0200 |
commit | 1a10bd84a5d103f6e1fdcd960f8377e3d099d773 (patch) | |
tree | 718038b157e964efcc5a502cdfcea6f636783a52 /gcc/doc | |
parent | 75d20d6c84c12bedd65a904e462f02f0b9eb3f77 (diff) | |
download | gcc-1a10bd84a5d103f6e1fdcd960f8377e3d099d773.zip gcc-1a10bd84a5d103f6e1fdcd960f8377e3d099d773.tar.gz gcc-1a10bd84a5d103f6e1fdcd960f8377e3d099d773.tar.bz2 |
frange class to represent floating point ranges
This implements a basic frange class to represent floating point
ranges. Although it is meant to be a base for further development, it
is enough to handle relations and propagate NAN and other properties.
For ranger clients to become floating point aware, we still need the
range-op entries, which I will submit later this week. Since those
entries require specialized FP knowledge, I will ask for a review from
the FP experts before committing.
Once range-op entries come live, all ranger clients that have been
converted to the type agnostic vrange API will become FP aware: evrp,
DOM, the threaders, loop-ch, etc. (Still missing is loop unswitching,
as a lot of the int_range* temporaries should be Value_Range. I don't
have enough cycles to convert loop unswitching, but could gladly give
guidance. It should be straightforward for those familiar with the
code ;-)).
Samples things we handle:
* We can set the FP properties (!NAN, !INF, etc) at assignment from
constants (and propagate them throughout the CFG):
float z = 0.0;
if (__builtin_isnan (z))
link_error ();
* The relation oracle works in tandem with the FP ranges:
if (x > y)
;
else if (!__builtin_isnan (x) && !__builtin_isnan (y))
{
// If x and y are not NAN, the x <= y relationship holds, and the
// following conditional can be folded away.
if (x <= y)
bar ();
}
* We know the true side of all ordered conditionals (except !=)
implies !NAN:
if (x > y)
{
if (__builtin_isnan (x) || __builtin_isnan (y))
link_error ();
}
Range-ops also works correctly with -ffinite-math-only, and avoids
checking for NANs, etc.
I believe this is enough to get a fully fleshed out floating point
support for evrp and friends, but doing so is beyond my limited FP
knowledge. For example, frange could be enhanced to track constant
endpoints, and we could track other FP properties aside from NAN.
Further discussion is gladly welcome.
Tested on x86-64 Linux.
gcc/ChangeLog:
* value-range-pretty-print.cc (vrange_printer::visit): New.
(vrange_printer::print_frange_prop): New.
* value-range-pretty-print.h (class vrange_printer): Add visit and
print_frange_prop.
* value-range-storage.h (vrange_allocator::alloc_vrange): Handle frange.
(vrange_allocator::alloc_frange): New.
* value-range.cc (vrange::operator=): Handle frange.
(vrange::operator==): Same.
(frange::accept): New.
(frange::set): New.
(frange::normalize_kind): New.
(frange::union_): New.
(frange::intersect): New.
(frange::operator=): New.
(frange::operator==): New.
(frange::supports_type_p): New.
(frange::verify_range): New.
* value-range.h (enum value_range_discriminator): Handle frange.
(class fp_prop): New.
(FP_PROP_ACCESSOR): New.
(class frange_props): New.
(FRANGE_PROP_ACCESSOR): New.
(class frange): New.
(Value_Range::init): Handle frange.
(Value_Range::operator=): Same.
(Value_Range::supports_type_p): Same.
(frange_props::operator==): New.
(frange_props::union_): New.
(frange_props::intersect): New
(frange::frange): New.
(frange::type): New.
(frange::set_varying): New.
(frange::set_undefined): New.
Diffstat (limited to 'gcc/doc')
0 files changed, 0 insertions, 0 deletions