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
[sil-generic-specializer] Don't specialize types which are too wide or too deep #7994
Conversation
@swift-ci please smoke test |
lib/SILOptimizer/Utils/Generics.cpp
Outdated
return std::make_pair(Depth, Width); | ||
} | ||
|
||
if (auto FnTy = t->getAs<SILFunctionType>()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have to handle metatypes;
func foo<T>(t: T) {
foo(t: T.self)
}
This produces T.Type.Type.Type...
Also, function types can appear in unlowered position:
func foo<T>(t: [T]) {
foo(t: [{ t[0] }])
}
This produces Array<() -> () -> () -> ... -> T>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good points! I'll handle those cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this works just as well:
unsigned complexity = 0;
type.visit([&](Type t) { complexity++; });
if (complexity < 1000) ...
Then you don't have to special-case anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an interesting idea. If it would work, it would simplify a lot the code here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@slavapestov I tried out this idea. It work nicely on all the examples you proposed. But it hangs the compiler on the computeNat
test in specialize_deep_generics.swift
. This is because in this example, the complexity of the type increases vertically
very slowly. And since complexity
does not distinguish between the growth of the type depth and the growth of the width, there is no easy way to bail earlier.
lib/SILOptimizer/Utils/Generics.cpp
Outdated
static const unsigned BoundGenericDepthThreshold = 50; | ||
// a bound generic type with the depth higher than this threshold | ||
static const unsigned TypeDepthThreshold = 50; | ||
// Set the width threshold rather high, because some projects uses very wide |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think checking the width is necessary, we have no way to make a type 'wider' by your definition without also making it 'deeper'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the test-case added in this PR results in very wide tuples, which are not very deep ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was the reason why I added the width checks. This way we bail faster if the width of the type grows much faster than depth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. This test case has O(2^n)
width and O(n)
height. :-)
I'm waiting for the first "compile-time computation using Swift's generic specializer" blog post. :) |
ff91ece
to
93a954f
Compare
…r too deep This improves the existing logic which is used to stop specialization for types that are too big to handle. It catches some pathological cases which hang the compiler. Fixes rdar://30938882
93a954f
to
f07743b
Compare
@swift-ci please smoke test |
1 similar comment
@swift-ci please smoke test |
This improves the existing logic which is used to stop specialization for types that are too big to handle. It catches some pathological cases which hang the compiler.
Fixes rdar://30938882