From: Andrew MacLeod <amacleod@redhat.com>
To: Jiufu Guo <guojiufu@linux.ibm.com>, Richard Biener <rguenther@suse.de>
Cc: Aldy Hernandez <aldyh@redhat.com>,
gcc-patches@gcc.gnu.org, jeffreyalaw@gmail.com,
richard.sandiford@arm.com, segher@kernel.crashing.org,
dje.gcc@gmail.com, linkw@gcc.gnu.org, bergner@linux.ibm.com
Subject: Re: [PATCH V4] Optimize '(X - N * M) / N' to 'X / N - M' if valid
Date: Mon, 17 Jul 2023 13:24:06 -0400 [thread overview]
Message-ID: <e61178a2-0209-31d6-ba85-63186b70a379@redhat.com> (raw)
In-Reply-To: <7nsf9mzm73.fsf@ltcden2-lp1.aus.stglabs.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 3218 bytes --]
On 7/17/23 09:45, Jiufu Guo wrote:
>
>>> Should we decide we would like it in general, it wouldnt be hard to add to
>>> irange. wi_fold() cuurently returns null, it could easily return a bool
>>> indicating if an overflow happened, and wi_fold_in_parts and fold_range would
>>> simply OR the results all together of the compoent wi_fold() calls. It would
>>> require updating/audfiting a number of range-op entries and adding an
>>> overflowed_p() query to irange.
>> Ah, yeah - the folding APIs would be a good fit I guess. I was
>> also looking to have the "new" helpers to be somewhat consistent
>> with the ranger API.
>>
>> So if we had a fold_range overload with either an output argument
>> or a flag that makes it return false on possible overflow that
>> would work I guess? Since we have a virtual class setup we
>> might be able to provide a default failing method and implement
>> workers for plus and mult (as needed for this patch) as the need
>> arises?
> Thanks for your comments!
> Here is a concern. The patterns in match.pd may be supported by
> 'vrp' passes. At that time, the range info would be computed (via
> the value-range machinery) and cached for each SSA_NAME. In the
> patterns, when range_of_expr is called for a capture, the range
> info is retrieved from the cache, and no need to fold_range again.
> This means the overflow info may also need to be cached together
> with other range info. There may be additional memory and time
> cost.
>
I've been thinking about this a little bit, and how to make the info
available in a useful way.
I wonder if maybe we just add another entry point to range-ops that
looks a bit like fold_range ..
Attached is an (untested) patch which ads overflow_free_p(op1, op2,
relation) to rangeops. It defaults to returning false. If you want
to implement it for say plus, you'd add to operator_plus in
range-ops.cc something like
operator_plus::overflow_free_p (irange&op1, irange& op2, relation_kind)
{
// stuff you do in plus_without_overflow
}
I added relation_kind as param, but you can ignore it. maybe it wont
ever help, but it seems like if we know there is a relation between op1
and op2 we might be able to someday determine something else? if
not, remove it.
Then all you need to do too access it is to go thru range-op_handler..
so for instance:
range_op_handler (PLUS_EXPR).overflow_free_p (op1, op2)
It'll work for all types an all tree codes. the dispatch machinery will
return false unless both op1 and op2 are integral ranges, and then it
will invoke the appropriate handler, defaulting to returning FALSE.
I also am not a fan of the get_range routine. It would be better to
generally just call range_of_expr, get the results, then handle
undefined in the new overflow_free_p() routine and return false.
varying should not need anything special since it will trigger the
overflow when you do the calculation.
The auxillary routines could go in vr-values.h/cc. They seem like
things that simplify_using_ranges could utilize, and when we get to
integrating simplify_using_ranges better, what you are doing may end up
there anyway
Does that work?
Andrew
[-- Attachment #2: ofp.diff --]
[-- Type: text/x-patch, Size: 1895 bytes --]
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index d1c735ee6aa..f2a863db286 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -366,6 +366,24 @@ range_op_handler::op1_op2_relation (const vrange &lhs) const
}
}
+bool
+range_op_handler::overflow_free_p (const vrange &lh,
+ const vrange &rh,
+ relation_trio rel) const
+{
+ gcc_checking_assert (m_operator);
+ switch (dispatch_kind (lh, lh, rh))
+ {
+ case RO_III:
+ return m_operator->overflow_free_p(as_a <irange> (lh),
+ as_a <irange> (rh),
+ rel);
+ default:
+ return false;
+ }
+}
+
+
// Convert irange bitmasks into a VALUE MASK pair suitable for calling CCP.
@@ -688,6 +706,13 @@ range_operator::op1_op2_relation_effect (irange &lhs_range ATTRIBUTE_UNUSED,
return false;
}
+bool
+range_operator::overflow_free_p (const irange &, const irange &,
+ relation_trio) const
+{
+ return false;
+}
+
// Apply any known bitmask updates based on this operator.
void
diff --git a/gcc/range-op.h b/gcc/range-op.h
index af94c2756a7..db3b03f28a5 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -147,6 +147,9 @@ public:
virtual relation_kind op1_op2_relation (const irange &lhs) const;
virtual relation_kind op1_op2_relation (const frange &lhs) const;
+
+ virtual bool overflow_free_p (const irange &lh, const irange &rh,
+ relation_trio = TRIO_VARYING) const;
protected:
// Perform an integral operation between 2 sub-ranges and return it.
virtual void wi_fold (irange &r, tree type,
@@ -214,6 +217,8 @@ public:
const vrange &op2,
relation_kind = VREL_VARYING) const;
relation_kind op1_op2_relation (const vrange &lhs) const;
+ bool overflow_free_p (const vrange &lh, const vrange &rh,
+ relation_trio = TRIO_VARYING) const;
protected:
unsigned dispatch_kind (const vrange &lhs, const vrange &op1,
const vrange& op2) const;
next prev parent reply other threads:[~2023-07-17 17:24 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-11 9:04 Jiufu Guo
2023-07-14 11:27 ` Aldy Hernandez
2023-07-14 13:37 ` Richard Biener
2023-07-14 14:12 ` Aldy Hernandez
2023-07-14 21:00 ` Andrew MacLeod
2023-07-17 6:27 ` Jiufu Guo
2023-07-17 9:24 ` Richard Biener
2023-07-17 13:45 ` Jiufu Guo
2023-07-17 17:24 ` Andrew MacLeod [this message]
2023-07-18 9:44 ` Jiufu Guo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e61178a2-0209-31d6-ba85-63186b70a379@redhat.com \
--to=amacleod@redhat.com \
--cc=aldyh@redhat.com \
--cc=bergner@linux.ibm.com \
--cc=dje.gcc@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=guojiufu@linux.ibm.com \
--cc=jeffreyalaw@gmail.com \
--cc=linkw@gcc.gnu.org \
--cc=rguenther@suse.de \
--cc=richard.sandiford@arm.com \
--cc=segher@kernel.crashing.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).