]>
Commit | Line | Data |
---|---|---|
38a73435 | 1 | /* Header file for range operator class. |
7adcbafe | 2 | Copyright (C) 2017-2022 Free Software Foundation, Inc. |
38a73435 AH |
3 | Contributed by Andrew MacLeod <amacleod@redhat.com> |
4 | and Aldy Hernandez <aldyh@redhat.com>. | |
5 | ||
6 | This file is part of GCC. | |
7 | ||
8 | GCC is free software; you can redistribute it and/or modify it under | |
9 | the terms of the GNU General Public License as published by the Free | |
10 | Software Foundation; either version 3, or (at your option) any later | |
11 | version. | |
12 | ||
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with GCC; see the file COPYING3. If not see | |
20 | <http://www.gnu.org/licenses/>. */ | |
21 | ||
22 | #ifndef GCC_RANGE_OP_H | |
23 | #define GCC_RANGE_OP_H | |
24 | ||
25 | // This class is implemented for each kind of operator supported by | |
26 | // the range generator. It serves various purposes. | |
27 | // | |
28 | // 1 - Generates range information for the specific operation between | |
29 | // two ranges. This provides the ability to fold ranges for an | |
30 | // expression. | |
31 | // | |
32 | // 2 - Performs range algebra on the expression such that a range can be | |
33 | // adjusted in terms of one of the operands: | |
34 | // | |
35 | // def = op1 + op2 | |
36 | // | |
37 | // Given a range for def, we can adjust the range so that it is in | |
38 | // terms of either operand. | |
39 | // | |
40 | // op1_range (def_range, op2) will adjust the range in place so it | |
41 | // is in terms of op1. Since op1 = def - op2, it will subtract | |
42 | // op2 from each element of the range. | |
43 | // | |
44 | // 3 - Creates a range for an operand based on whether the result is 0 or | |
45 | // non-zero. This is mostly for logical true false, but can serve other | |
46 | // purposes. | |
47 | // ie 0 = op1 - op2 implies op2 has the same range as op1. | |
48 | ||
49 | class range_operator | |
50 | { | |
51 | public: | |
52 | // Perform an operation between 2 ranges and return it. | |
4ba9fb0a AH |
53 | virtual bool fold_range (irange &r, tree type, |
54 | const irange &lh, | |
80dd13f5 AM |
55 | const irange &rh, |
56 | relation_kind rel = VREL_NONE) const; | |
38a73435 AH |
57 | |
58 | // Return the range for op[12] in the general case. LHS is the range for | |
59 | // the LHS of the expression, OP[12]is the range for the other | |
60 | // | |
61 | // The operand and the result is returned in R. | |
62 | // | |
63 | // TYPE is the expected type of the range. | |
64 | // | |
65 | // Return TRUE if the operation is performed and a valid range is available. | |
66 | // | |
67 | // i.e. [LHS] = ??? + OP2 | |
68 | // is re-formed as R = [LHS] - OP2. | |
4ba9fb0a AH |
69 | virtual bool op1_range (irange &r, tree type, |
70 | const irange &lhs, | |
80dd13f5 AM |
71 | const irange &op2, |
72 | relation_kind rel = VREL_NONE) const; | |
4ba9fb0a AH |
73 | virtual bool op2_range (irange &r, tree type, |
74 | const irange &lhs, | |
80dd13f5 AM |
75 | const irange &op1, |
76 | relation_kind rel = VREL_NONE) const; | |
38a73435 | 77 | |
80dd13f5 AM |
78 | // The following routines are used to represent relations between the |
79 | // various operations. If the caller knows where the symbolics are, | |
80 | // it can query for relationships between them given known ranges. | |
81 | virtual enum tree_code lhs_op1_relation (const irange &lhs, | |
82 | const irange &op1, | |
83 | const irange &op2) const; | |
84 | virtual enum tree_code lhs_op2_relation (const irange &lhs, | |
85 | const irange &op1, | |
86 | const irange &op2) const; | |
87 | virtual enum tree_code op1_op2_relation (const irange &lhs) const; | |
38a73435 | 88 | protected: |
f674b4a7 | 89 | // Perform an integral operation between 2 sub-ranges and return it. |
4ba9fb0a | 90 | virtual void wi_fold (irange &r, tree type, |
bb74ef9e AM |
91 | const wide_int &lh_lb, |
92 | const wide_int &lh_ub, | |
93 | const wide_int &rh_lb, | |
94 | const wide_int &rh_ub) const; | |
80dd13f5 AM |
95 | // Side effect of relation for generic fold_range clients. |
96 | virtual bool op1_op2_relation_effect (irange &lhs_range, tree type, | |
97 | const irange &op1_range, | |
98 | const irange &op2_range, | |
99 | relation_kind rel) const; | |
704e8a82 AM |
100 | // Called by fold range to split small subranges into parts. |
101 | void wi_fold_in_parts (irange &r, tree type, | |
102 | const wide_int &lh_lb, | |
103 | const wide_int &lh_ub, | |
104 | const wide_int &rh_lb, | |
105 | const wide_int &rh_ub) const; | |
38a73435 AH |
106 | }; |
107 | ||
108 | extern range_operator *range_op_handler (enum tree_code code, tree type); | |
4ba9fb0a | 109 | extern void range_cast (irange &, tree type); |
8f119c55 AH |
110 | extern void wi_set_zero_nonzero_bits (tree type, |
111 | const wide_int &, const wide_int &, | |
112 | wide_int &maybe_nonzero, | |
113 | wide_int &mustbe_nonzero); | |
38a73435 AH |
114 | |
115 | #endif // GCC_RANGE_OP_H |