RISC-V: Fix snafu in SI mode splitters patch
[official-gcc.git] / gcc / config / aarch64 / fractional-cost.h
blobf7f2309c03e9aebd7dd814e9c61f40ce5019d3dd
1 // Simple fixed-point representation of fractional costs
2 // Copyright (C) 2021-2024 Free Software Foundation, Inc.
3 //
4 // This file is part of GCC.
5 //
6 // GCC is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation; either version 3, or (at your option) any later
9 // version.
11 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 // for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with GCC; see the file COPYING3. If not see
18 // <http://www.gnu.org/licenses/>.
20 // A simple saturating fixed-point type for representing fractional
21 // intermediate results in cost calculations. The input and result
22 // costs are assumed to be uint32_ts. Unlike sreal, the class can
23 // represent most values that we care about exactly (without rounding).
24 // See the comment above the SCALE field for the current set of
25 // exactly-representable reciprocals.
26 class fractional_cost
28 public:
29 // Construct an object equal to INT_VALUE.
30 constexpr fractional_cost (uint32_t int_value = 0)
31 : m_value (uint64_t (int_value) * SCALE) {}
33 fractional_cost (uint32_t a, uint32_t b);
35 fractional_cost operator+ (const fractional_cost &) const;
36 fractional_cost operator- (const fractional_cost &) const;
37 fractional_cost operator* (uint32_t) const;
39 fractional_cost &operator+= (const fractional_cost &);
40 fractional_cost &operator-= (const fractional_cost &);
41 fractional_cost &operator*= (uint32_t);
43 bool operator== (const fractional_cost &) const;
44 bool operator!= (const fractional_cost &) const;
45 bool operator< (const fractional_cost &) const;
46 bool operator<= (const fractional_cost &) const;
47 bool operator>= (const fractional_cost &) const;
48 bool operator> (const fractional_cost &) const;
50 uint32_t ceil () const;
52 static uint32_t scale (uint32_t, fractional_cost, fractional_cost);
54 explicit operator bool () const { return m_value != 0; }
56 // Convert the value to a double.
57 double as_double () const { return double (m_value) / SCALE; }
59 private:
60 enum raw { RAW };
61 constexpr fractional_cost (uint64_t value, raw) : m_value (value) {}
63 // A multiple of [1, 16] * 16. This ensures that 1/N is representable
64 // for every possible SVE element count N, or for any "X per cycle"
65 // value N in the range [1, 16].
66 static const uint32_t SCALE = 11531520;
68 // The value multiplied by BIAS.
69 uint64_t m_value;
72 // Construct a representation of A / B, rounding up if (contrary to
73 // expectations) we can't represent the value exactly. For now we
74 // treat inexact values as a bug, since all values of B should come
75 // from a small set of values that are known at compile time.
76 inline fractional_cost::fractional_cost (uint32_t a, uint32_t b)
77 : m_value (CEIL (uint64_t (a) * SCALE, uint64_t (b)))
79 gcc_checking_assert (SCALE % b == 0);
82 inline fractional_cost
83 fractional_cost::operator+ (const fractional_cost &other) const
85 uint64_t sum = m_value + other.m_value;
86 return { sum >= m_value ? sum : ~uint64_t (0), RAW };
89 inline fractional_cost &
90 fractional_cost::operator+= (const fractional_cost &other)
92 *this = *this + other;
93 return *this;
96 inline fractional_cost
97 fractional_cost::operator- (const fractional_cost &other) const
99 uint64_t diff = m_value - other.m_value;
100 return { diff <= m_value ? diff : 0, RAW };
103 inline fractional_cost &
104 fractional_cost::operator-= (const fractional_cost &other)
106 *this = *this - other;
107 return *this;
110 inline fractional_cost
111 fractional_cost::operator* (uint32_t other) const
113 if (other == 0)
114 return 0;
116 uint64_t max = ~uint64_t (0);
117 return { m_value <= max / other ? m_value * other : max, RAW };
120 inline fractional_cost &
121 fractional_cost::operator*= (uint32_t other)
123 *this = *this * other;
124 return *this;
127 inline bool
128 fractional_cost::operator== (const fractional_cost &other) const
130 return m_value == other.m_value;
133 inline bool
134 fractional_cost::operator!= (const fractional_cost &other) const
136 return m_value != other.m_value;
139 inline bool
140 fractional_cost::operator< (const fractional_cost &other) const
142 return m_value < other.m_value;
145 inline bool
146 fractional_cost::operator<= (const fractional_cost &other) const
148 return m_value <= other.m_value;
151 inline bool
152 fractional_cost::operator>= (const fractional_cost &other) const
154 return m_value >= other.m_value;
157 inline bool
158 fractional_cost::operator> (const fractional_cost &other) const
160 return m_value > other.m_value;
163 // Round the value up to the nearest integer and saturate to a uint32_t.
164 inline uint32_t
165 fractional_cost::ceil () const
167 uint32_t max = ~uint32_t (0);
168 if (m_value <= uint64_t (max - 1) * SCALE)
169 return (m_value + SCALE - 1) / SCALE;
170 return max;
173 // Round (COST * A) / B up to the nearest integer and saturate to a uint32_t.
174 inline uint32_t
175 fractional_cost::scale (uint32_t cost, fractional_cost a, fractional_cost b)
177 widest_int result = wi::div_ceil (widest_int (cost) * a.m_value,
178 b.m_value, SIGNED);
179 if (result < ~uint32_t (0))
180 return result.to_shwi ();
181 return ~uint32_t (0);
184 inline fractional_cost
185 operator+ (uint32_t a, const fractional_cost &b)
187 return b.operator+ (a);
190 inline fractional_cost
191 operator- (uint32_t a, const fractional_cost &b)
193 return fractional_cost (a).operator- (b);
196 inline fractional_cost
197 operator* (uint32_t a, const fractional_cost &b)
199 return b.operator* (a);
202 inline bool
203 operator== (uint32_t a, const fractional_cost &b)
205 return b.operator== (a);
208 inline bool
209 operator!= (uint32_t a, const fractional_cost &b)
211 return b.operator!= (a);
214 inline bool
215 operator< (uint32_t a, const fractional_cost &b)
217 return b.operator> (a);
220 inline bool
221 operator<= (uint32_t a, const fractional_cost &b)
223 return b.operator>= (a);
226 inline bool
227 operator>= (uint32_t a, const fractional_cost &b)
229 return b.operator<= (a);
232 inline bool
233 operator> (uint32_t a, const fractional_cost &b)
235 return b.operator< (a);