Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a macro to opt into aggressive constprop #38080

Merged
merged 1 commit into from
Jan 26, 2021
Merged

Conversation

Keno
Copy link
Member

@Keno Keno commented Oct 17, 2020

Right now aggressive constprop is essentially tied to the inlining
threshold (or to function's name being getproperty or setproperty!
respectively), which can be both somewhat brittle if the inlining cost
changes and insufficient when you do really know that const prop
would be beneficial even if the function is not inlineable. This
adds a simple macro that can be used to manually annotate methods
to force aggressive constprop on them.

@Keno Keno requested review from vtjnash and JeffBezanson October 17, 2020 22:07
Copy link
Member

@timholy timholy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like it!

base/expr.jl Outdated Show resolved Hide resolved
test/core.jl Outdated Show resolved Hide resolved
test/core.jl Outdated
# The first test just makes sure that improvements to the compiler don't
# render the annotation effectless.
@test Base.return_types(f_nonaggressive, Tuple{Int})[1] == Val
@test Base.return_types(f_aggressive, Tuple{Int})[1] == Val{1}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move these to test/compiler/inference

@@ -22,7 +22,8 @@ mutable struct Serializer{I<:IO} <: AbstractSerializer
table::IdDict{Any,Any}
pending_refs::Vector{Int}
known_object_data::Dict{UInt64,Any}
Serializer{I}(io::I) where I<:IO = new(io, 0, IdDict(), Int[], Dict{UInt64,Any}())
version::Int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably a good idea, but I still usually try to handle these by making the data fully self-describing, i.e. store the new field in such a way that the type of value you deserialize tells you which version of the object you have.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I tried at first, but it just becomes super messy, for what seems to be little benefit. I don't see a realistic way to support non-versioned serialization blobs stably, so we might as well require the version.

@Keno Keno force-pushed the kf/aggressive_constprop branch from 794883c to ffcbab1 Compare December 17, 2020 08:47
@Keno
Copy link
Member Author

Keno commented Dec 17, 2020

I've rebased this. @JeffBezanson could I bother you to change the Serialization code to your satisfaction. I'm still not entirely convinced I understand why we can't just do the simple version-based thing - the current tricks in there just seem extremely brittle and non-scalable, but if you'd prefer the other thing, I guess that's ok - I just the feature ;).

@vtjnash
Copy link
Member

vtjnash commented Dec 17, 2020

Why is this useful, when it's not inlined, so this code will typically not be what ends up getting run? Do we need instead some degrees of @inline strength?

@Keno
Copy link
Member Author

Keno commented Dec 17, 2020

Why wouldn't it be useful? Aggressive constprop affects the return type we infer, so even if it's not inlined, sharper type information in the caller can make for a much more efficient function.

@JeffBezanson
Copy link
Member

Ok, I think we might as well merge this as-is.

@@ -716,6 +721,7 @@ function readheader(s::AbstractSerializer)
error("""Cannot read stream serialized with a newer version of Julia.
Got data version $version > current version $ser_version""")
end
s.version = version
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
end
nothing
end

test/core.jl Outdated
@@ -7527,4 +7527,4 @@ const RedefineVarargN{N} = Tuple{Vararg{RedefineVararg, N}}
const RedefineVarargN{N} = Tuple{Vararg{RedefineVararg, N}}

# NTuples with non-types
@test NTuple{3, 2} == Tuple{2, 2, 2}
@test NTuple{3, 2} == Tuple{2, 2, 2}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated (and slightly worse)

@timholy
Copy link
Member

timholy commented Jan 5, 2021

Does it make any sense to also have a way of blocking constant-prop? I'm thinking #38983. It seems pretty cheap to reinfer for specific constants in many cases, though maybe not all. So 🤷‍♂️

@JeffBezanson
Copy link
Member

Yes that would make sense. We've seen cases (though it's fairly rare) where it's useful to manually block constant prop.

@vtjnash
Copy link
Member

vtjnash commented Jan 5, 2021

We have @noinline already that will do that, but I think the observation there is that we want to consider @nospecialize and avoid inspecting specific typed specializations.

@timholy
Copy link
Member

timholy commented Jan 6, 2021

We have @noinline already that will do that, but I think the observation there is that we want to consider @nospecialize and avoid inspecting specific typed specializations.

Good point although I'm pretty sure @noinline doesn't prevent constant-prop on Core.kwfunc and possibly (haven't checked) Base.bodyfunction methods. The first is probably cheap, the second (if it happens) maybe not so much. xref tlienart/Franklin.jl#752 (comment).

@timholy
Copy link
Member

timholy commented Jan 9, 2021

I don't want to derail this from its original purpose, so please see #38983 (comment).

@Keno Keno force-pushed the kf/aggressive_constprop branch 3 times, most recently from f62c2ef to e077e86 Compare January 22, 2021 17:14
Right now aggressive constprop is essentially tied to the inlining
threshold (or to their name being `getproperty` or `setproperty!`
respectively, which can be both somewhat brittle if the inlining cost
changes and insufficient when you do really know that const prop
would be beneficial even if the function is not inlineable. This
adds a simple macro that can be used to manually annotate methods
to force aggressive constprop on them.
@Keno Keno force-pushed the kf/aggressive_constprop branch from e077e86 to 20ad41c Compare January 22, 2021 17:43
@Keno Keno closed this Jan 23, 2021
@Keno Keno reopened this Jan 23, 2021
@Keno Keno closed this Jan 25, 2021
@Keno Keno reopened this Jan 25, 2021
@Keno Keno merged commit 3ea80fb into master Jan 26, 2021
@Keno Keno deleted the kf/aggressive_constprop branch January 26, 2021 00:46
ElOceanografo pushed a commit to ElOceanografo/julia that referenced this pull request May 4, 2021
Right now aggressive constprop is essentially tied to the inlining
threshold (or to their name being `getproperty` or `setproperty!`
respectively, which can be both somewhat brittle if the inlining cost
changes and insufficient when you do really know that const prop
would be beneficial even if the function is not inlineable. This
adds a simple macro that can be used to manually annotate methods
to force aggressive constprop on them.
antoine-levitt pushed a commit to antoine-levitt/julia that referenced this pull request May 9, 2021
Right now aggressive constprop is essentially tied to the inlining
threshold (or to their name being `getproperty` or `setproperty!`
respectively, which can be both somewhat brittle if the inlining cost
changes and insufficient when you do really know that const prop
would be beneficial even if the function is not inlineable. This
adds a simple macro that can be used to manually annotate methods
to force aggressive constprop on them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants