@@ -58,6 +58,9 @@ following meanings:
58
58
methods are `:consistent` with their non-overlayed original counterparts
59
59
(see [`Base.@assume_effects`](@ref) for the exact definition of `:consistenct`-cy).
60
60
* `ALWAYS_FALSE`: this method may invoke overlayed methods.
61
+ - `nortcall::Bool`: this method does not call `Core.Compiler.return_type`,
62
+ and it is guaranteed that any other methods this method might call also do not call
63
+ `Core.Compiler.return_type`.
61
64
62
65
Note that the representations above are just internal implementation details and thus likely
63
66
to change in the future. See [`Base.@assume_effects`](@ref) for more detailed explanation
@@ -103,6 +106,9 @@ The output represents the state of different effect properties in the following
103
106
- `+o` (green): `ALWAYS_TRUE`
104
107
- `-o` (red): `ALWAYS_FALSE`
105
108
- `?o` (yellow): `CONSISTENT_OVERLAY`
109
+ 9. `:nortcall` (`r`):
110
+ - `+r` (green): `true`
111
+ - `-r` (red): `false`
106
112
"""
107
113
struct Effects
108
114
consistent:: UInt8
@@ -113,6 +119,7 @@ struct Effects
113
119
inaccessiblememonly:: UInt8
114
120
noub:: UInt8
115
121
nonoverlayed:: UInt8
122
+ nortcall:: Bool
116
123
function Effects (
117
124
consistent:: UInt8 ,
118
125
effect_free:: UInt8 ,
@@ -121,7 +128,8 @@ struct Effects
121
128
notaskstate:: Bool ,
122
129
inaccessiblememonly:: UInt8 ,
123
130
noub:: UInt8 ,
124
- nonoverlayed:: UInt8 )
131
+ nonoverlayed:: UInt8 ,
132
+ nortcall:: Bool )
125
133
return new (
126
134
consistent,
127
135
effect_free,
@@ -130,7 +138,8 @@ struct Effects
130
138
notaskstate,
131
139
inaccessiblememonly,
132
140
noub,
133
- nonoverlayed)
141
+ nonoverlayed,
142
+ nortcall)
134
143
end
135
144
end
136
145
@@ -160,10 +169,10 @@ const NOUB_IF_NOINBOUNDS = 0x01 << 1
160
169
# :nonoverlayed bits
161
170
const CONSISTENT_OVERLAY = 0x01 << 1
162
171
163
- const EFFECTS_TOTAL = Effects (ALWAYS_TRUE, ALWAYS_TRUE, true , true , true , ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE)
164
- const EFFECTS_THROWS = Effects (ALWAYS_TRUE, ALWAYS_TRUE, false , true , true , ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE)
165
- const EFFECTS_UNKNOWN = Effects (ALWAYS_FALSE, ALWAYS_FALSE, false , false , false , ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_TRUE) # unknown mostly, but it's not overlayed at least (e.g. it's not a call)
166
- const _EFFECTS_UNKNOWN = Effects (ALWAYS_FALSE, ALWAYS_FALSE, false , false , false , ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_FALSE) # unknown really
172
+ const EFFECTS_TOTAL = Effects (ALWAYS_TRUE, ALWAYS_TRUE, true , true , true , ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, true )
173
+ const EFFECTS_THROWS = Effects (ALWAYS_TRUE, ALWAYS_TRUE, false , true , true , ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, true )
174
+ const EFFECTS_UNKNOWN = Effects (ALWAYS_FALSE, ALWAYS_FALSE, false , false , false , ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_TRUE, false ) # unknown mostly, but it's not overlayed at least (e.g. it's not a call)
175
+ const _EFFECTS_UNKNOWN = Effects (ALWAYS_FALSE, ALWAYS_FALSE, false , false , false , ALWAYS_FALSE, ALWAYS_FALSE, ALWAYS_FALSE, false ) # unknown really
167
176
168
177
function Effects (effects:: Effects = _EFFECTS_UNKNOWN;
169
178
consistent:: UInt8 = effects. consistent,
@@ -173,7 +182,8 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN;
173
182
notaskstate:: Bool = effects. notaskstate,
174
183
inaccessiblememonly:: UInt8 = effects. inaccessiblememonly,
175
184
noub:: UInt8 = effects. noub,
176
- nonoverlayed:: UInt8 = effects. nonoverlayed)
185
+ nonoverlayed:: UInt8 = effects. nonoverlayed,
186
+ nortcall:: Bool = effects. nortcall)
177
187
return Effects (
178
188
consistent,
179
189
effect_free,
@@ -182,7 +192,8 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN;
182
192
notaskstate,
183
193
inaccessiblememonly,
184
194
noub,
185
- nonoverlayed)
195
+ nonoverlayed,
196
+ nortcall)
186
197
end
187
198
188
199
function is_better_effects (new:: Effects , old:: Effects )
@@ -247,6 +258,11 @@ function is_better_effects(new::Effects, old::Effects)
247
258
elseif new. nonoverlayed != old. nonoverlayed
248
259
return false
249
260
end
261
+ if new. nortcall
262
+ any_improved |= ! old. nortcall
263
+ elseif new. nortcall != old. nortcall
264
+ return false
265
+ end
250
266
return any_improved
251
267
end
252
268
@@ -259,7 +275,8 @@ function merge_effects(old::Effects, new::Effects)
259
275
merge_effectbits (old. notaskstate, new. notaskstate),
260
276
merge_effectbits (old. inaccessiblememonly, new. inaccessiblememonly),
261
277
merge_effectbits (old. noub, new. noub),
262
- merge_effectbits (old. nonoverlayed, new. nonoverlayed))
278
+ merge_effectbits (old. nonoverlayed, new. nonoverlayed),
279
+ merge_effectbits (old. nortcall, new. nortcall))
263
280
end
264
281
265
282
function merge_effectbits (old:: UInt8 , new:: UInt8 )
@@ -279,16 +296,18 @@ is_inaccessiblememonly(effects::Effects) = effects.inaccessiblememonly === ALWAY
279
296
is_noub (effects:: Effects ) = effects. noub === ALWAYS_TRUE
280
297
is_noub_if_noinbounds (effects:: Effects ) = effects. noub === NOUB_IF_NOINBOUNDS
281
298
is_nonoverlayed (effects:: Effects ) = effects. nonoverlayed === ALWAYS_TRUE
299
+ is_nortcall (effects:: Effects ) = effects. nortcall
282
300
283
301
# implies `is_notaskstate` & `is_inaccessiblememonly`, but not explicitly checked here
284
- is_foldable (effects:: Effects ) =
302
+ is_foldable (effects:: Effects , check_rtcall :: Bool = false ) =
285
303
is_consistent (effects) &&
286
304
(is_noub (effects) || is_noub_if_noinbounds (effects)) &&
287
305
is_effect_free (effects) &&
288
- is_terminates (effects)
306
+ is_terminates (effects) &&
307
+ (! check_rtcall || is_nortcall (effects))
289
308
290
- is_foldable_nothrow (effects:: Effects ) =
291
- is_foldable (effects) &&
309
+ is_foldable_nothrow (effects:: Effects , check_rtcall :: Bool = false ) =
310
+ is_foldable (effects, check_rtcall ) &&
292
311
is_nothrow (effects)
293
312
294
313
# TODO add `is_noub` here?
@@ -318,7 +337,8 @@ function encode_effects(e::Effects)
318
337
((e. notaskstate % UInt32) << 7 ) |
319
338
((e. inaccessiblememonly % UInt32) << 8 ) |
320
339
((e. noub % UInt32) << 10 ) |
321
- ((e. nonoverlayed % UInt32) << 12 )
340
+ ((e. nonoverlayed % UInt32) << 12 ) |
341
+ ((e. nortcall % UInt32) << 14 )
322
342
end
323
343
324
344
function decode_effects (e:: UInt32 )
@@ -330,7 +350,8 @@ function decode_effects(e::UInt32)
330
350
_Bool ((e >> 7 ) & 0x01 ),
331
351
UInt8 ((e >> 8 ) & 0x03 ),
332
352
UInt8 ((e >> 10 ) & 0x03 ),
333
- UInt8 ((e >> 12 ) & 0x03 ))
353
+ UInt8 ((e >> 12 ) & 0x03 ),
354
+ _Bool ((e >> 14 ) & 0x01 ))
334
355
end
335
356
336
357
function encode_effects_override (eo:: EffectsOverride )
@@ -345,6 +366,7 @@ function encode_effects_override(eo::EffectsOverride)
345
366
eo. noub && (e |= (0x0001 << 7 ))
346
367
eo. noub_if_noinbounds && (e |= (0x0001 << 8 ))
347
368
eo. consistent_overlay && (e |= (0x0001 << 9 ))
369
+ eo. nortcall && (e |= (0x0001 << 10 ))
348
370
return e
349
371
end
350
372
@@ -359,7 +381,8 @@ function decode_effects_override(e::UInt16)
359
381
! iszero (e & (0x0001 << 6 )),
360
382
! iszero (e & (0x0001 << 7 )),
361
383
! iszero (e & (0x0001 << 8 )),
362
- ! iszero (e & (0x0001 << 9 )))
384
+ ! iszero (e & (0x0001 << 9 )),
385
+ ! iszero (e & (0x0001 << 10 )))
363
386
end
364
387
365
388
decode_statement_effects_override (ssaflag:: UInt32 ) =
0 commit comments