1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//! How many times a loop goes round, and how many bytes a walk inside it covers.
//!
//! Two passes want this and they want it for opposite reasons, which is why it is here rather than
//! in either of them.
//!
//! [`crate::hoist`] wants it as a fact. It puts one check in front of a loop covering every access
//! the loop makes, so a count that is too small is a check that covers less than the loop reads and
//! a bug that goes unreported. Everything the count rests on has to be discharged before that check
//! is written, which is what the assumptions below are about.
//!
//! [`crate::split`] wants it as an estimate. What it does with the number is ask the runtime how
//! many of those bytes really belong to the object, and it believes the answer rather than the
//! question. A count that is too small there costs iterations in the half of the loop that still
//! has its checks, and a count that is too large costs a slightly longer walk in the runtime. So
//! that pass reads a count from any exit it can get one from, and this file gives the same number
//! to both callers and lets each decide what it is worth.
use ;
use crateLoopId;
use crate;
/// What is reported for a loop whose count is not settled.
pub const NOT_COUNTED: &str =
"loop left alone, how many times it runs is not settled before it starts";
/// What is reported for a loop whose count is settled only if its counter does not wrap.
pub const RESTS_ON_NO_WRAP: &str =
"loop left alone, how many times it runs is known only if its counter does not wrap";
/// How many times a loop goes round, which comes out either as a number or as an expression.
pub
/// How many times the loop goes round, when a caller may believe it.
///
/// Goes round, and not runs, and the difference is the whole of an off by one. What the analysis
/// answers is the iteration at which the exit test first fails, which is how many times the back
/// edge is taken. A block that runs before that test runs one more time than that, because it ran
/// on the way to the test that ended the loop as well as on the way to all the ones that did not.
/// Every check hoisting takes out is in such a block, which is what it reads this number with.
///
/// Not [`crate::scev::Bound::proven`], and the difference is one assumption, which is why a count
/// that is a number is read through [`crate::scev::Bound::under_undefined_overflow`] and the
/// reasoning behind that is written there.
///
/// A count that is an expression is read here instead, because it is allowed one assumption that
/// accessor refuses. [`Assumption::Approaching`] says the counter starts on the near side of its
/// limit, and [`covered`] discharges it rather than believing it, by clamping the count at zero. A
/// count that comes out negative is a loop whose test failed the first time it ran, which for a
/// bottom tested loop is a loop that went round no times, and zero is what that loop's extent is
/// worked out from.
///
/// What the reading is for is the widening. The count is built out of the limit operand of the exit
/// test, that operand is a value of the counter's own type, and which number it is depends on how
/// the test read it. A limit past the middle of a thirty two bit type is a large number to an
/// unsigned test and a negative one to a signed test, so an extent computed by sign extending what
/// an unsigned test compared would clamp to zero and leave a check covering one element in front of
/// a loop reading thousands. The reading is carried through to [`covered`], which spends it on a
/// sign extension or a zero extension, and to the caller, which is where anything about how large
/// the count can be belongs.
pub
/// Builds how many bytes a walk covers, out of a count nobody has as a number.
///
/// `max(scale * value + offset, 0) * step + reach`, in the order it reads. The widening is the one
/// the exit test the count came from asks for where there is one to do, a sign extension for a
/// signed test and a zero extension for an unsigned one. The clamp is [`Assumption::Approaching`]
/// paid for rather than assumed, and it is a `select` rather than a branch because the whole of this
/// has to be straight line code in a preheader.
///
/// The `flags` are what the caller is willing to say about the arithmetic, and the two callers say
/// different things. Hoisting bounds the count against the width of its type before it asks for any
/// of this, so nothing here can leave sixty four bits and `nsw` is a fact it earned. Splitting does
/// no such bounding, because the number is a limit on how far the runtime looks and a limit that
/// wrapped is still answered with a true count of bytes, so it asks for none and takes what plain
/// wrapping arithmetic gives it.
///
/// The clamp stays on the unsigned side even though a zero extension is never negative, because what
/// can be negative is the count rather than the value it is built out of: `for (unsigned i = 5; i <
/// n; i++)` has an offset of minus five and an `n` of one is a loop that runs no times.
///
/// The trivial steps are left out where the numbers make them trivial. Nothing after this pass folds
/// a multiply by one, so a walk of single bytes would otherwise leave one in every preheader.
pub
/// The instruction that produced a value the builder just made.
pub