]> git.lizzy.rs Git - rust.git/blob - src/test/codegen/coverage-experiments/src/match_with_increment_alt.rs
explained lang_item function body (count_code_region)
[rust.git] / src / test / codegen / coverage-experiments / src / match_with_increment_alt.rs
1 #![feature(core_intrinsics)]
2 //static TEST_FUNC_NAME: &'static [u8; 7] = b"main()\0";
3   static TEST_FUNC_NAME: &'static [u8; 6] = b"main()";
4 fn main() {
5     unsafe { core::intrinsics::instrprof_increment(TEST_FUNC_NAME as *const u8, 1234 as u64, 3 as u32, 0 as u32) };
6     let a = 1;
7     let b = 10;
8     let _result = match a < b {
9         true => {
10             unsafe { core::intrinsics::instrprof_increment(TEST_FUNC_NAME as *const u8, 1234 as u64, 3 as u32, 1 as u32) };
11             true
12         }
13         _ => false,
14     };
15 }
16
17 /*
18
19 ALTERNATE APPROACH:
20
21     IS IT MUCH EASIER TO INSERT COUNTERS AT THE TOP OF A REGION THAT MUST EXECUTE IN ENTIRETY IF
22     PANIC DOES NOT OCCUR? AND WHAT IF WE ADD SUPPORT FOR PANIC UNWIND (later)?
23
24     IS THERE A DETRACTOR COMPARED TO THE DEFERRED APPROACH WHEN CONSIDERING EXPRESSIONS MAY HAVE EARLY RETURNS?
25
26     (BECAUSE, WE STILL NEED TO COUNT THE REGION LEADING UP TO THE EXPRESSION ANYWAY)
27
28 =================================================
29 =================================================
30
31 To inject an intrinsic after computing a final expression value of a coverage region:
32
33 Replace the following basic block end (last statement plus terminator):
34
35 ... <statements to compute _4> ...
36 StorageLive(_4)
37 StorageLive(_5)
38 _5 = _1
39 StorageLive(_6)
40 _6 = _2
41 _4 = Lt(move _5, move _6)
42 StorageDead(_6)
43 StorageDead(_5)
44                              <------ to insert instrprof_increment() here
45 FakeRead(ForMatchedPlace, _4)
46 --------------------------------------------------------------------------------------
47 switchInt(_4)
48
49
50 =================================================
51 Insert call to intrinsic with:
52
53 StorageLive(_4)        # _4 is now meant for deferred FakeRead(ForMatchdPlace, _4) in BasicBlock after increment() call
54 StorageLive(_5)                 # Unchanged except _4 is now _5
55 StorageLive(_6)                 # Unchanged except _5 is now _6
56 _6 = _1                         # Unchanged except _5 is now _6
57 StorageLive(_7)                 # Unchanged except _6 is now _7
58 _7 = _2                         # Unchanged except _6 is now _7
59 _5 = Lt(move _6, move _7)       # Unchanged except _4, _5, _6 is now _5, _6, _7
60 StorageDead(_7)                 # Unchanged except _6 is now _7
61 StorageDead(_6)                 # Unchanged except _5 is now _6
62
63 FakeRead(ForLet, _5)   # CHANGED ForMatchedPlace to ForLet
64
65 > # ALL NEW AND NECESSARY TO CALL instrprof_increment()
66 > StorageLive(_8)        # ?? stores function pointer to instrprof_increment function?
67 > StorageLive(_9)
68 > StorageLive(_10)
69 > StorageLive(_11)
70 > _11 = const {alloc1+0: &&[u8; 6]}
71 > _10 = &raw const (*(*_11))
72 > _9 = move _10 as *const u8 (Pointer(ArrayToPointer))
73 > StorageDead(_10)
74 > StorageLive(_12)
75 > _12 = const 1234u64
76 > StorageLive(_13)
77 > _13 = const 3u32
78 > StorageLive(_14)
79 > _14 = const 0u32
80 > --------------------------------------------------------------------------------------
81 > _8 = const std::intrinsics::instrprof_increment(move _9, move _12, move _13, move _14)
82 >
83 > -> return
84 >
85 > StorageDead(_14)
86 > StorageDead(_13)
87 > StorageDead(_12)
88 > StorageDead(_9)
89 > StorageDead(_11)
90 > StorageDead(_8)
91
92 _4 = _5                         # ARE THESE LINES REDUNDANT? CAN I JUST PASS _5 DIRECTLY TO FakeRead()?
93 StorageDead(_5)                 # DROP "_t" temp result of `let _t = a < b`
94                                 # (NOTE THAT IF SO, I CAN REMOVE _5 altogether, and use _4, which coincidentally makes less changes)
95                                 # SEE BELOW
96
97 FakeRead(ForMatchedPlace, _4)   # Unchanged
98 --------------------------------------------------------------------------------------
99 switchInt(_4)                   # Unchanged
100
101
102 =================================================
103 Can I skip the extra variable and insert call to intrinsic with:
104
105 StorageLive(_4)             # Unchanged
106 StorageLive(_5)             # Unchanged
107 _5 = _1                     # Unchanged
108 StorageLive(_6)             # Unchanged
109 _6 = _2                     # Unchanged
110 _4 = Lt(move _5, move _6)   # Unchanged
111 StorageDead(_6)             # Unchanged
112 StorageDead(_5)             # Unchanged
113
114 > # ALL NEW AND NECESSARY TO CALL instrprof_increment()
115 > FakeRead(ForLet, _4)   # Save the post-increment result in temp "_t"
116 > StorageLive(_8)        # ?? stores function pointer to instrprof_increment function?
117 > StorageLive(_9)
118 > StorageLive(_10)
119 > StorageLive(_11)
120 > _11 = const {alloc1+0: &&[u8; 6]}
121 > _10 = &raw const (*(*_11))
122 > _9 = move _10 as *const u8 (Pointer(ArrayToPointer))
123 > StorageDead(_10)
124 > StorageLive(_12)
125 > _12 = const 1234u64
126 > StorageLive(_13)
127 > _13 = const 3u32
128 > StorageLive(_14)
129 > _14 = const 0u32
130 > --------------------------------------------------------------------------------------
131 > _8 = const std::intrinsics::instrprof_increment(move _9, move _12, move _13, move _14)
132 >
133 > -> return
134 >
135 > StorageDead(_14)
136 > StorageDead(_13)
137 > StorageDead(_12)
138 > StorageDead(_9)
139 > StorageDead(_11)
140 > StorageDead(_8)
141
142 FakeRead(ForMatchedPlace, _4)   # Unchanged  (PREVIOUSLY USED IN FakeRead(ForLet), is that OK?)
143 --------------------------------------------------------------------------------------
144 switchInt(_4)                   # Unchanged
145
146
147
148
149
150 =================================================
151 =================================================
152
153 For the second inserted call to instrprof_increment, without that call we have:
154
155 --------------------------------------------------------------------------------------
156 switchInt(_4)                   # From above
157
158 -> otherwise   # that is, "NOT false"
159
160 _3 = const true
161                              <------ to insert instrprof_increment() here
162 --------------------------------------------------------------------------------------
163 goto
164
165 ->                              # No label. No condition, and not a "return"
166
167 FakeRead(ForLet, _3)            # NOTE: Unused result
168 StorageDead(_4)
169 _0 = ()
170 StorageDead(_3)
171 StorageDead(_2)
172 StorageDead(_1)
173 --------------------------------------------------------------------------------------
174 goto
175
176 ->                              # No label. No condition, and not a "return"
177
178 return   # from main()
179
180
181 =================================================
182 With the call to increment():
183
184 --------------------------------------------------------------------------------------
185 switchInt(_4)                   # From above
186
187 -> otherwise   # "NOT false"    # UNCHANGED
188
189 StorageLive(_15)                # CHANGED! Allocated new storage (_15) for the result of match, if true.
190 _15 = const true                # UNCHANGED except _3 is now _15
191 FakeRead(ForLet, _15)           # CHANGED! Assign value to temporary (to be assigned to _3 later) ... Do I need to do this?
192
193 > # ALL NEW AND NECESSARY TO CALL instrprof_increment()
194 > StorageLive(_16)                # pointer to instrprof_increment() function ?
195 > StorageLive(_17)
196 > StorageLive(_18)
197 > StorageLive(_19)
198 > _19 = const {alloc1+0: &&[u8; 6]}
199 > _18 = &raw const (*(*_19))
200 > _17 = move _18 as *const u8 (Pointer(ArrayToPointer))
201 > StorageDead(_18)
202 > StorageLive(_20)
203 > _20 = const 1234u64
204 > StorageLive(_21)
205 > _21 = const 3u32
206 > StorageLive(_22)
207 > _22 = const 1u32
208 > --------------------------------------------------------------------------------------
209 > _16 = const std::intrinsics::instrprof_increment(move _17, move _20, move _21, move _22)
210 >
211 > ->  return
212 >
213 > StorageDead(_22)
214 > StorageDead(_21)
215 > StorageDead(_20)
216 > StorageDead(_17)
217 > StorageDead(_19)
218 > StorageDead(_16)
219 > _3 = _15
220 > StorageDead(_15)
221
222 --------------------------------# UNCHANGED-------------------------------------------
223 goto                            # UNCHANGED
224
225 ->                              # UNCHANGED
226
227 FakeRead(ForLet, _3)            # UNCHANGED
228 StorageDead(_4)                 # UNCHANGED
229 _0 = ()                         # UNCHANGED
230 StorageDead(_3)                 # UNCHANGED
231 StorageDead(_2)                 # UNCHANGED
232 StorageDead(_1)                 # UNCHANGED
233 --------------------------------------------------------------------------------------
234 goto                            # UNCHANGED
235
236 ->                              # UNCHANGED
237
238 return   # from main()          # UNCHANGED
239
240 =================================================
241 As before, can I skip the extra variable (_15) and insert the call to intrinsic with _3 directly?:
242
243
244 --------------------------------------------------------------------------------------
245 switchInt(_4)                   # From above
246
247 -> otherwise   # "NOT false"    # UNCHANGED
248
249 _3 = const true                 # UNCHANGED?
250
251 > # ALL NEW AND NECESSARY TO CALL instrprof_increment()
252 > StorageLive(_16)                # pointer to instrprof_increment() function ?
253 > StorageLive(_17)
254 > StorageLive(_18)
255 > StorageLive(_19)
256 > _19 = const {alloc1+0: &&[u8; 6]}
257 > _18 = &raw const (*(*_19))
258 > _17 = move _18 as *const u8 (Pointer(ArrayToPointer))
259 > StorageDead(_18)
260 > StorageLive(_20)
261 > _20 = const 1234u64
262 > StorageLive(_21)
263 > _21 = const 3u32
264 > StorageLive(_22)
265 > _22 = const 1u32
266 > --------------------------------------------------------------------------------------
267 > _16 = const std::intrinsics::instrprof_increment(move _17, move _20, move _21, move _22)
268 >
269 > ->  return
270 >
271 > StorageDead(_22)
272 > StorageDead(_21)
273 > StorageDead(_20)
274 > StorageDead(_17)
275 > StorageDead(_19)
276 > StorageDead(_16)
277
278 --------------------------------# UNCHANGED-------------------------------------------
279 goto                            # UNCHANGED
280
281 ->                              # UNCHANGED
282
283 FakeRead(ForLet, _3)            # UNCHANGED
284 StorageDead(_4)                 # UNCHANGED
285 _0 = ()                         # UNCHANGED
286 StorageDead(_3)                 # UNCHANGED
287 StorageDead(_2)                 # UNCHANGED
288 StorageDead(_1)                 # UNCHANGED
289 --------------------------------------------------------------------------------------
290 goto                            # UNCHANGED
291
292 ->                              # UNCHANGED
293
294 return   # from main()          # UNCHANGED
295
296 */