From b224766ecf79f2848c1b2645007a74610b647d9b Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 21 Aug 2022 06:41:16 -0400 Subject: [PATCH 1/4] Remove invalidating `!` overloads Running things downstream, life seems to go on without them just fine. Found in https://github.com/SciML/DifferentialEquations.jl/issues/786 and https://github.com/SciML/Static.jl/issues/77, these methods contribute to a ton of recompilation. Methods that cause lots of compilation but aren't used? Bye bye. Users of Static.jl can just manually handle `!`. It's safe because it just throws an error otherwise. We can put it in an FAQ if it's that much of an issue. But this is definitely not worth causing seconds of JIT lag downstream. --- src/Static.jl | 5 +++-- test/runtests.jl | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Static.jl b/src/Static.jl index 82ab248..9123019 100644 --- a/src/Static.jl +++ b/src/Static.jl @@ -423,8 +423,9 @@ Base.xor(::StaticInteger{X}, ::StaticInteger{Y}) where {X, Y} = static(xor(X, Y) Base.xor(::StaticInteger{X}, y::Union{Integer, Missing}) where {X} = xor(X, y) Base.xor(x::Union{Integer, Missing}, ::StaticInteger{Y}) where {Y} = xor(x, Y) -Base.:(!)(::True) = False() -Base.:(!)(::False) = True() +# These are heavily invalidating, leading to major compile time increases downstream +#Base.:(!)(::True) = False() +#Base.:(!)(::False) = True() Base.all(::Tuple{Vararg{True}}) = true Base.all(::Tuple{Vararg{Union{True, False}}}) = false diff --git a/test/runtests.jl b/test/runtests.jl index 502ee35..4a52ced 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -117,8 +117,6 @@ end @test @inferred(~t) === f @test @inferred(~f) === t - @test @inferred(!t) === f - @test @inferred(!f) === t @test @inferred(+t) === StaticInt(1) @test @inferred(+f) === StaticInt(0) @test @inferred(-t) === StaticInt(-1) From 792fe18720dcd93acfae763c3e8c770fdd60406f Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 21 Aug 2022 06:47:24 -0400 Subject: [PATCH 2/4] fix test --- src/Static.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Static.jl b/src/Static.jl index 9123019..1c01c51 100644 --- a/src/Static.jl +++ b/src/Static.jl @@ -746,7 +746,7 @@ end """ eq(x, y) -Equivalent to `!=` but if `x` and `y` are both static returns a `StaticBool. +Equivalent to `!=` but if `x` and `y` are both static returns a `StaticBool`. """ eq(x::X, y::Y) where {X, Y} = ifelse(is_static(X) & is_static(Y), static, identity)(x == y) eq(x) = Base.Fix2(eq, x) @@ -754,15 +754,15 @@ eq(x) = Base.Fix2(eq, x) """ ne(x, y) -Equivalent to `!=` but if `x` and `y` are both static returns a `StaticBool. +Equivalent to `!=` but if `x` and `y` are both static returns a `StaticBool`. """ -ne(x::X, y::Y) where {X, Y} = !eq(x, y) +ne(x::X, y::Y) where {X, Y} = ifelse(is_static(X) & is_static(Y), static, identity)(x != y) ne(x) = Base.Fix2(ne, x) """ gt(x, y) -Equivalent to `>` but if `x` and `y` are both static returns a `StaticBool. +Equivalent to `>` but if `x` and `y` are both static returns a `StaticBool`. """ gt(x::X, y::Y) where {X, Y} = ifelse(is_static(X) & is_static(Y), static, identity)(x > y) gt(x) = Base.Fix2(gt, x) @@ -770,7 +770,7 @@ gt(x) = Base.Fix2(gt, x) """ ge(x, y) -Equivalent to `>=` but if `x` and `y` are both static returns a `StaticBool. +Equivalent to `>=` but if `x` and `y` are both static returns a `StaticBool`. """ ge(x::X, y::Y) where {X, Y} = ifelse(is_static(X) & is_static(Y), static, identity)(x >= y) ge(x) = Base.Fix2(ge, x) @@ -778,7 +778,7 @@ ge(x) = Base.Fix2(ge, x) """ le(x, y) -Equivalent to `<=` but if `x` and `y` are both static returns a `StaticBool. +Equivalent to `<=` but if `x` and `y` are both static returns a `StaticBool`. """ le(x::X, y::Y) where {X, Y} = ifelse(is_static(X) & is_static(Y), static, identity)(x <= y) le(x) = Base.Fix2(le, x) @@ -786,7 +786,7 @@ le(x) = Base.Fix2(le, x) """ lt(x, y) -Equivalent to `<` but if `x` and `y` are both static returns a `StaticBool. +Equivalent to `<` but if `x` and `y` are both static returns a `StaticBool`. """ lt(x::X, y::Y) where {X, Y} = ifelse(is_static(X) & is_static(Y), static, identity)(x < y) lt(x) = Base.Fix2(lt, x) From 133096a41fea42260517e45cc78b58f5d1fe4ad8 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 21 Aug 2022 10:10:25 -0400 Subject: [PATCH 3/4] give back the functionality in a non-invalidating way --- src/Static.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Static.jl b/src/Static.jl index 1c01c51..0157069 100644 --- a/src/Static.jl +++ b/src/Static.jl @@ -3,7 +3,7 @@ module Static import IfElse: ifelse export StaticInt, StaticFloat64, StaticSymbol, True, False, StaticBool, NDIndex -export dynamic, is_static, known, static, static_promote +export dynamic, is_static, known, static, static_promote, static_! """ StaticSymbol @@ -315,7 +315,6 @@ Base.inv(x::StaticNumber{N}) where {N} = one(x) / x @inline Base.iseven(@nospecialize x::StaticNumber) = iseven(known(x)) @inline Base.isodd(@nospecialize x::StaticNumber) = isodd(known(x)) - Base.AbstractFloat(x::StaticNumber) = StaticFloat64(x) Base.abs(::StaticNumber{N}) where {N} = static(abs(N)) @@ -426,6 +425,9 @@ Base.xor(x::Union{Integer, Missing}, ::StaticInteger{Y}) where {Y} = xor(x, Y) # These are heavily invalidating, leading to major compile time increases downstream #Base.:(!)(::True) = False() #Base.:(!)(::False) = True() +# Instead, use the not invalidating form +static_!(::True) = False() +static_!(::False) = True() Base.all(::Tuple{Vararg{True}}) = true Base.all(::Tuple{Vararg{Union{True, False}}}) = false From 1e43bfa2a67f64601ad066d0b63c88876793e1d6 Mon Sep 17 00:00:00 2001 From: Chris Rackauckas Date: Sun, 21 Aug 2022 10:12:18 -0400 Subject: [PATCH 4/4] handle bool case --- src/Static.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Static.jl b/src/Static.jl index 0157069..4a79800 100644 --- a/src/Static.jl +++ b/src/Static.jl @@ -426,6 +426,7 @@ Base.xor(x::Union{Integer, Missing}, ::StaticInteger{Y}) where {Y} = xor(x, Y) #Base.:(!)(::True) = False() #Base.:(!)(::False) = True() # Instead, use the not invalidating form +static_!(x::Bool) = !x static_!(::True) = False() static_!(::False) = True()