-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Specialize Functions #3306
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
Specialize Functions #3306
Conversation
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.
Hello, and thank you for opening this PR! 🎉
All contributors have signed the CLA, thank you! ❤️
Have an awesome day! ☀️
test performance please |
performance test scheduled: 2 job(s) in queue, 0 running. |
val typeParams = tp.cls.typeRef.baseType(func).argInfos | ||
val interface = specInterface(typeParams) | ||
|
||
if (interface.exists && tp.decls.lookup(nme.apply).exists) { |
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.
Instead of creating a class symbol with specInterface
and checking if it actually exists, you can use isSpecializableFunction
like in https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala#L39
dt.vparamss.head.map(_.symbol.info) | ||
) | ||
|
||
val specializedApply = tree.symbol.enclosingClass.info.decls.lookup(specName) |
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.
Same thing here and in transformApply, you should only have to do the lookup if isSpecializableFunction
returns true
case _ => tree | ||
} | ||
|
||
@inline private def specializedName(name: Name, args: List[Type])(implicit ctx: Context) = |
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 there's any reason for this method and the next one to be marked @inline
r <- List(UnitType, BooleanType, IntType, FloatType, LongType, DoubleType) | ||
t1 <- List(IntType, LongType, DoubleType) | ||
t2 <- List(IntType, LongType, DoubleType) | ||
} yield specApply(func2, List(t1, t2), r) |
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 duplicates some logic from isSpecializableFunction
Performance test finished successfully: Visit http://dotty-bench.epfl.ch/3306/ to see the changes. Benchmarks is based on merging with master (b8d1e41) |
Most of the performance cost is probably from splitting a phase group to add SpecializeFunctions. Would be great if we could figure out a way to avoid that. |
cd2766f
to
e916a67
Compare
I think I managed to re-unify the group I split 🎉 |
test performance please |
performance test scheduled: 1 job(s) in queue, 0 running. |
performance test failed: Error line number: 145 [check /data/workspace/bench/logs/pull-3306-10-28-17.33.out for more information] |
test performance please |
performance test scheduled: 1 job(s) in queue, 0 running. |
Performance test finished successfully: Visit http://dotty-bench.epfl.ch/3306/ to see the changes. Benchmarks is based on merging with master (68cc7ee) |
test performance please (meta test for bench infrastructure change) |
performance test scheduled: 1 job(s) in queue, 0 running. |
test performance please (meta test for bench infrastructure change) |
performance test scheduled: 1 job(s) in queue, 0 running. |
Performance test finished successfully: Visit http://dotty-bench.epfl.ch/3306/ to see the changes. Benchmarks is based on merging with master (68cc7ee) |
f5250fe
to
5ecc4aa
Compare
test performance please |
performance test scheduled: 1 job(s) in queue, 0 running. |
Performance test finished successfully: Visit http://dotty-bench.epfl.ch/3306/ to see the changes. Benchmarks is based on merging with master (22ff8a4) |
Looks like this PR still affects performance, even the empty file benchmark seems to get slower. It'd be good to try to figure out where the extra time is being spent and if we can optimize this. |
- Stop immediately if the type doesn't derive from `Function{0,1,2}` - We don't need to check if any of the parents derives from `Function{0,1,2}`, we can just check if the type derives from it.
5ecc4aa
to
a32b06f
Compare
test performance please |
performance test scheduled: 1 job(s) in queue, 0 running. |
Performance test finished successfully: Visit http://dotty-bench.epfl.ch/3306/ to see the changes. Benchmarks is based on merging with master (635d668) |
Supersedes #1807 by @felixmulder
What I changed compared to the previous version:
The previous version would change the parent of a class extending
FunctionN
to the specialised version, if it existed. I encountered several issues doing that, and my investigation led me to believe that doing so is not necessary in this particular case. From my reading of @dragos's thesis, §4.4.2 "Specialized inheritance", it appears that changing the parent to the specialised version is important to have the child inherit the specialised functions rather than the generic ones. My understanding is that this is not necessary in this particular case, please let me know if I am misunderstanding the issue.The optimisation wouldn't apply on by-name parameters, because it would run before
ElimByName
. I didn't manage to shuffle the phases around without adding a new traversal.