Skip to content

Commit a545ab0

Browse files
authored
add @constprop for compatibility to 1.7 (#42298)
* add `@constprop` for compatibility to 1.7 This also adds a depwarn for `@aggressive_constprop`, which seemed sensible to me, given that it will be removed in 1.8.
1 parent 3b2c143 commit a545ab0

File tree

5 files changed

+59
-21
lines changed

5 files changed

+59
-21
lines changed

base/char.jl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ represents a valid Unicode character.
4545
"""
4646
Char
4747

48-
@aggressive_constprop (::Type{T})(x::Number) where {T<:AbstractChar} = T(UInt32(x))
49-
@aggressive_constprop AbstractChar(x::Number) = Char(x)
50-
@aggressive_constprop (::Type{T})(x::AbstractChar) where {T<:Union{Number,AbstractChar}} = T(codepoint(x))
51-
@aggressive_constprop (::Type{T})(x::AbstractChar) where {T<:Union{Int32,Int64}} = codepoint(x) % T
48+
@constprop :aggressive (::Type{T})(x::Number) where {T<:AbstractChar} = T(UInt32(x))
49+
@constprop :aggressive AbstractChar(x::Number) = Char(x)
50+
@constprop :aggressive (::Type{T})(x::AbstractChar) where {T<:Union{Number,AbstractChar}} = T(codepoint(x))
51+
@constprop :aggressive (::Type{T})(x::AbstractChar) where {T<:Union{Int32,Int64}} = codepoint(x) % T
5252
(::Type{T})(x::T) where {T<:AbstractChar} = x
5353

5454
"""
@@ -75,7 +75,7 @@ return a different-sized integer (e.g. `UInt8`).
7575
"""
7676
function codepoint end
7777

78-
@aggressive_constprop codepoint(c::Char) = UInt32(c)
78+
@constprop :aggressive codepoint(c::Char) = UInt32(c)
7979

8080
struct InvalidCharError{T<:AbstractChar} <: Exception
8181
char::T
@@ -124,7 +124,7 @@ See also [`decode_overlong`](@ref) and [`show_invalid`](@ref).
124124
"""
125125
isoverlong(c::AbstractChar) = false
126126

127-
@aggressive_constprop function UInt32(c::Char)
127+
@constprop :aggressive function UInt32(c::Char)
128128
# TODO: use optimized inline LLVM
129129
u = bitcast(UInt32, c)
130130
u < 0x80000000 && return u >> 24
@@ -148,7 +148,7 @@ that support overlong encodings should implement `Base.decode_overlong`.
148148
"""
149149
function decode_overlong end
150150

151-
@aggressive_constprop function decode_overlong(c::Char)
151+
@constprop :aggressive function decode_overlong(c::Char)
152152
u = bitcast(UInt32, c)
153153
l1 = leading_ones(u)
154154
t0 = trailing_zeros(u) & 56
@@ -158,7 +158,7 @@ function decode_overlong end
158158
((u & 0x007f0000) >> 4) | ((u & 0x7f000000) >> 6)
159159
end
160160

161-
@aggressive_constprop function Char(u::UInt32)
161+
@constprop :aggressive function Char(u::UInt32)
162162
u < 0x80 && return bitcast(Char, u << 24)
163163
u < 0x00200000 || throw_code_point_err(u)
164164
c = ((u << 0) & 0x0000003f) | ((u << 2) & 0x00003f00) |
@@ -169,14 +169,14 @@ end
169169
bitcast(Char, c)
170170
end
171171

172-
@aggressive_constprop @noinline UInt32_cold(c::Char) = UInt32(c)
173-
@aggressive_constprop function (T::Union{Type{Int8},Type{UInt8}})(c::Char)
172+
@constprop :aggressive @noinline UInt32_cold(c::Char) = UInt32(c)
173+
@constprop :aggressive function (T::Union{Type{Int8},Type{UInt8}})(c::Char)
174174
i = bitcast(Int32, c)
175175
i 0 ? ((i >>> 24) % T) : T(UInt32_cold(c))
176176
end
177177

178-
@aggressive_constprop @noinline Char_cold(b::UInt32) = Char(b)
179-
@aggressive_constprop function Char(b::Union{Int8,UInt8})
178+
@constprop :aggressive @noinline Char_cold(b::UInt32) = Char(b)
179+
@constprop :aggressive function Char(b::Union{Int8,UInt8})
180180
0 b 0x7f ? bitcast(Char, (b % UInt32) << 24) : Char_cold(UInt32(b))
181181
end
182182

base/deprecated.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,18 @@ end
262262
# This function was marked as experimental and not exported.
263263
@deprecate catch_stack(task=current_task(); include_bt=true) current_exceptions(task; backtrace=include_bt) false
264264

265+
"""
266+
@aggressive_constprop ex
267+
@aggressive_constprop(ex)
268+
269+
`@aggressive_constprop` requests more aggressive interprocedural constant
270+
propagation for the annotated function. For a method where the return type
271+
depends on the value of the arguments, this can yield improved inference results
272+
at the cost of additional compile time.
273+
"""
274+
macro aggressive_constprop(ex)
275+
depwarn("use `@constprop :aggressive ex` instead of `@aggressive_constprop ex`", :var"@aggressive_constprop")
276+
esc(isa(ex, Expr) ? pushmeta!(ex, :aggressive_constprop) : ex)
277+
end
278+
265279
# END 1.7 deprecations

base/expr.jl

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,25 @@ macro pure(ex)
240240
end
241241

242242
"""
243-
@aggressive_constprop ex
244-
@aggressive_constprop(ex)
243+
@constprop setting ex
244+
@constprop(setting, ex)
245245
246-
`@aggressive_constprop` requests more aggressive interprocedural constant
247-
propagation for the annotated function. For a method where the return type
248-
depends on the value of the arguments, this can yield improved inference results
249-
at the cost of additional compile time.
246+
`@constprop` controls the mode of interprocedural constant propagation for the
247+
annotated function. Only `:aggressive` is supported in 1.7:
248+
249+
- `@constprop :aggressive ex`: apply constant propagation aggressively.
250+
For a method where the return type depends on the value of the arguments,
251+
this can yield improved inference results at the cost of additional compile time.
252+
253+
`@constprop :none ex` is a no-op, but is allowed for compatibility with Julia 1.8.
250254
"""
251-
macro aggressive_constprop(ex)
252-
esc(isa(ex, Expr) ? pushmeta!(ex, :aggressive_constprop) : ex)
255+
macro constprop(setting, ex)
256+
if isa(setting, QuoteNode)
257+
setting = setting.value
258+
end
259+
setting === :aggressive && return esc(isa(ex, Expr) ? pushmeta!(ex, :aggressive_constprop) : ex)
260+
setting === :none && return esc(ex)
261+
throw(ArgumentError("@constprop $setting not supported"))
253262
end
254263

255264
"""

test/compiler/inference.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3171,15 +3171,18 @@ f_inf_error_bottom(x::Vector) = isempty(x) ? error(x[1]) : x
31713171

31723172
# @aggressive_constprop
31733173
@noinline g_nonaggressive(y, x) = Val{x}()
3174-
@noinline @Base.aggressive_constprop g_aggressive(y, x) = Val{x}()
3174+
@noinline @Base.constprop :aggressive g_aggressive(y, x) = Val{x}()
3175+
@noinline @Base.constprop :none g_nonaggressive2(y, x) = Val{x}()
31753176

31763177
f_nonaggressive(x) = g_nonaggressive(x, 1)
31773178
f_aggressive(x) = g_aggressive(x, 1)
3179+
f_nonaggressive2(x) = g_nonaggressive2(x, 1)
31783180

31793181
# The first test just makes sure that improvements to the compiler don't
31803182
# render the annotation effectless.
31813183
@test Base.return_types(f_nonaggressive, Tuple{Int})[1] == Val
31823184
@test Base.return_types(f_aggressive, Tuple{Int})[1] == Val{1}
3185+
@test Base.return_types(f_nonaggressive2, Tuple{Int})[1] == Val
31833186

31843187
function splat_lotta_unions()
31853188
a = Union{Tuple{Int},Tuple{String,Vararg{Int}},Tuple{Int,Vararg{Int}}}[(2,)][1]

test/deprecation_exec.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,15 @@ global_logger(prev_logger)
120120
end
121121

122122
# END 0.7 deprecations
123+
124+
# @aggressive_constprop
125+
@noinline g_nonaggressive(y, x) = Val{x}()
126+
@noinline @Base.aggressive_constprop g_aggressive(y, x) = Val{x}()
127+
128+
f_nonaggressive(x) = g_nonaggressive(x, 1)
129+
f_aggressive(x) = g_aggressive(x, 1)
130+
131+
# The first test just makes sure that improvements to the compiler don't
132+
# render the annotation effectless.
133+
@test Base.return_types(f_nonaggressive, Tuple{Int})[1] == Val
134+
@test Base.return_types(f_aggressive, Tuple{Int})[1] == Val{1}

0 commit comments

Comments
 (0)