]>
Commit | Line | Data |
---|---|---|
38a73435 | 1 | /* Header file for range operator class. |
8d9254fc | 2 | Copyright (C) 2017-2020 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. | |
f674b4a7 | 53 | virtual bool fold_range (value_range &r, tree type, |
bb74ef9e AM |
54 | const value_range &lh, |
55 | const value_range &rh) const; | |
38a73435 AH |
56 | |
57 | // Return the range for op[12] in the general case. LHS is the range for | |
58 | // the LHS of the expression, OP[12]is the range for the other | |
59 | // | |
60 | // The operand and the result is returned in R. | |
61 | // | |
62 | // TYPE is the expected type of the range. | |
63 | // | |
64 | // Return TRUE if the operation is performed and a valid range is available. | |
65 | // | |
66 | // i.e. [LHS] = ??? + OP2 | |
67 | // is re-formed as R = [LHS] - OP2. | |
028d81b1 AH |
68 | virtual bool op1_range (value_range &r, tree type, |
69 | const value_range &lhs, | |
70 | const value_range &op2) const; | |
71 | virtual bool op2_range (value_range &r, tree type, | |
72 | const value_range &lhs, | |
73 | const value_range &op1) const; | |
38a73435 AH |
74 | |
75 | protected: | |
f674b4a7 | 76 | // Perform an integral operation between 2 sub-ranges and return it. |
bb74ef9e AM |
77 | virtual void wi_fold (value_range &r, tree type, |
78 | const wide_int &lh_lb, | |
79 | const wide_int &lh_ub, | |
80 | const wide_int &rh_lb, | |
81 | const wide_int &rh_ub) const; | |
38a73435 AH |
82 | }; |
83 | ||
84 | extern range_operator *range_op_handler (enum tree_code code, tree type); | |
028d81b1 | 85 | extern void range_cast (value_range &, tree type); |
8f119c55 AH |
86 | extern void wi_set_zero_nonzero_bits (tree type, |
87 | const wide_int &, const wide_int &, | |
88 | wide_int &maybe_nonzero, | |
89 | wide_int &mustbe_nonzero); | |
38a73435 AH |
90 | |
91 | #endif // GCC_RANGE_OP_H |