@@ -58,6 +58,9 @@ following meanings:
5858 methods are `:consistent` with their non-overlayed original counterparts
5959 (see [`Base.@assume_effects`](@ref) for the exact definition of `:consistenct`-cy).
6060 * `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`.
6164
6265Note that the representations above are just internal implementation details and thus likely
6366to 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
103106 - `+o` (green): `ALWAYS_TRUE`
104107 - `-o` (red): `ALWAYS_FALSE`
105108 - `?o` (yellow): `CONSISTENT_OVERLAY`
109+ 9. `:nortcall` (`r`):
110+ - `+r` (green): `true`
111+ - `-r` (red): `false`
106112"""
107113struct Effects
108114 consistent:: UInt8
@@ -113,6 +119,7 @@ struct Effects
113119 inaccessiblememonly:: UInt8
114120 noub:: UInt8
115121 nonoverlayed:: UInt8
122+ nortcall:: Bool
116123 function Effects (
117124 consistent:: UInt8 ,
118125 effect_free:: UInt8 ,
@@ -121,7 +128,8 @@ struct Effects
121128 notaskstate:: Bool ,
122129 inaccessiblememonly:: UInt8 ,
123130 noub:: UInt8 ,
124- nonoverlayed:: UInt8 )
131+ nonoverlayed:: UInt8 ,
132+ nortcall:: Bool )
125133 return new (
126134 consistent,
127135 effect_free,
@@ -130,7 +138,8 @@ struct Effects
130138 notaskstate,
131139 inaccessiblememonly,
132140 noub,
133- nonoverlayed)
141+ nonoverlayed,
142+ nortcall)
134143 end
135144end
136145
@@ -160,10 +169,10 @@ const NOUB_IF_NOINBOUNDS = 0x01 << 1
160169# :nonoverlayed bits
161170const CONSISTENT_OVERLAY = 0x01 << 1
162171
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
167176
168177function Effects (effects:: Effects = _EFFECTS_UNKNOWN;
169178 consistent:: UInt8 = effects. consistent,
@@ -173,7 +182,8 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN;
173182 notaskstate:: Bool = effects. notaskstate,
174183 inaccessiblememonly:: UInt8 = effects. inaccessiblememonly,
175184 noub:: UInt8 = effects. noub,
176- nonoverlayed:: UInt8 = effects. nonoverlayed)
185+ nonoverlayed:: UInt8 = effects. nonoverlayed,
186+ nortcall:: Bool = effects. nortcall)
177187 return Effects (
178188 consistent,
179189 effect_free,
@@ -182,7 +192,8 @@ function Effects(effects::Effects = _EFFECTS_UNKNOWN;
182192 notaskstate,
183193 inaccessiblememonly,
184194 noub,
185- nonoverlayed)
195+ nonoverlayed,
196+ nortcall)
186197end
187198
188199function is_better_effects (new:: Effects , old:: Effects )
@@ -247,6 +258,11 @@ function is_better_effects(new::Effects, old::Effects)
247258 elseif new. nonoverlayed != old. nonoverlayed
248259 return false
249260 end
261+ if new. nortcall
262+ any_improved |= ! old. nortcall
263+ elseif new. nortcall != old. nortcall
264+ return false
265+ end
250266 return any_improved
251267end
252268
@@ -259,7 +275,8 @@ function merge_effects(old::Effects, new::Effects)
259275 merge_effectbits (old. notaskstate, new. notaskstate),
260276 merge_effectbits (old. inaccessiblememonly, new. inaccessiblememonly),
261277 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))
263280end
264281
265282function merge_effectbits (old:: UInt8 , new:: UInt8 )
@@ -279,16 +296,18 @@ is_inaccessiblememonly(effects::Effects) = effects.inaccessiblememonly === ALWAY
279296is_noub (effects:: Effects ) = effects. noub === ALWAYS_TRUE
280297is_noub_if_noinbounds (effects:: Effects ) = effects. noub === NOUB_IF_NOINBOUNDS
281298is_nonoverlayed (effects:: Effects ) = effects. nonoverlayed === ALWAYS_TRUE
299+ is_nortcall (effects:: Effects ) = effects. nortcall
282300
283301# implies `is_notaskstate` & `is_inaccessiblememonly`, but not explicitly checked here
284- is_foldable (effects:: Effects ) =
302+ is_foldable (effects:: Effects , check_rtcall :: Bool = false ) =
285303 is_consistent (effects) &&
286304 (is_noub (effects) || is_noub_if_noinbounds (effects)) &&
287305 is_effect_free (effects) &&
288- is_terminates (effects)
306+ is_terminates (effects) &&
307+ (! check_rtcall || is_nortcall (effects))
289308
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 ) &&
292311 is_nothrow (effects)
293312
294313# TODO add `is_noub` here?
@@ -318,7 +337,8 @@ function encode_effects(e::Effects)
318337 ((e. notaskstate % UInt32) << 7 ) |
319338 ((e. inaccessiblememonly % UInt32) << 8 ) |
320339 ((e. noub % UInt32) << 10 ) |
321- ((e. nonoverlayed % UInt32) << 12 )
340+ ((e. nonoverlayed % UInt32) << 12 ) |
341+ ((e. nortcall % UInt32) << 14 )
322342end
323343
324344function decode_effects (e:: UInt32 )
@@ -330,7 +350,8 @@ function decode_effects(e::UInt32)
330350 _Bool ((e >> 7 ) & 0x01 ),
331351 UInt8 ((e >> 8 ) & 0x03 ),
332352 UInt8 ((e >> 10 ) & 0x03 ),
333- UInt8 ((e >> 12 ) & 0x03 ))
353+ UInt8 ((e >> 12 ) & 0x03 ),
354+ _Bool ((e >> 14 ) & 0x01 ))
334355end
335356
336357function encode_effects_override (eo:: EffectsOverride )
@@ -345,6 +366,7 @@ function encode_effects_override(eo::EffectsOverride)
345366 eo. noub && (e |= (0x0001 << 7 ))
346367 eo. noub_if_noinbounds && (e |= (0x0001 << 8 ))
347368 eo. consistent_overlay && (e |= (0x0001 << 9 ))
369+ eo. nortcall && (e |= (0x0001 << 10 ))
348370 return e
349371end
350372
@@ -359,7 +381,8 @@ function decode_effects_override(e::UInt16)
359381 ! iszero (e & (0x0001 << 6 )),
360382 ! iszero (e & (0x0001 << 7 )),
361383 ! iszero (e & (0x0001 << 8 )),
362- ! iszero (e & (0x0001 << 9 )))
384+ ! iszero (e & (0x0001 << 9 )),
385+ ! iszero (e & (0x0001 << 10 )))
363386end
364387
365388decode_statement_effects_override (ssaflag:: UInt32 ) =
0 commit comments