[swift] master: Turn on dynamic super method dispatch by default (bd8d85d)


(Chris Lattner) #1

Random question: does this still use static dispatch when the superclass is within the same resilience domain, or is it the SIL optimizer’s job to handle that?

-Chris

···

On Jan 15, 2016, at 1:37 PM, David Farler via swift-commits <swift-commits@swift.org> wrote:

Repository : github.com/apple/swift
On branch : master
Link : github.com/apple/swift/commit/bd8d85da0a55498394a1e2d26f01cda38879a0bf

---------------------------------------------------------------

commit bd8d85da0a55498394a1e2d26f01cda38879a0bf
Author: David Farler <dfarler@apple.com>
Date: Fri Jan 15 11:55:28 2016 -0800

   Turn on dynamic super method dispatch by default

   This removes the -use-native-super-method flag and turns on dynamic
   dispatch for native method invocations on super by default.

   rdar://problem/22749732


(David Farler) #2

In SILGen, when the method isn't final, it does always emits a super_method instruction, but Roman added devirtualizer support for these, and it does look like they are getting optimized down to static dispatch when the nearest implementation is in the same module.

David

···

On Jan 17, 2016, at 2:06 PM, Chris Lattner <clattner@apple.com> wrote:

On Jan 15, 2016, at 1:37 PM, David Farler via swift-commits <swift-commits@swift.org> wrote:

Repository : github.com/apple/swift
On branch : master
Link : github.com/apple/swift/commit/bd8d85da0a55498394a1e2d26f01cda38879a0bf

---------------------------------------------------------------

commit bd8d85da0a55498394a1e2d26f01cda38879a0bf
Author: David Farler <dfarler@apple.com>
Date: Fri Jan 15 11:55:28 2016 -0800

  Turn on dynamic super method dispatch by default

  This removes the -use-native-super-method flag and turns on dynamic
  dispatch for native method invocations on super by default.

  rdar://problem/22749732

Random question: does this still use static dispatch when the superclass is within the same resilience domain, or is it the SIL optimizer’s job to handle that?

-Chris


(Chris Lattner) #3

Good news, thanks. Would it make sense for -O0 perf to have SILGen generate the static dispatch when possible, or is it too much trouble for the benefit?

-Chris

···

On Jan 17, 2016, at 2:49 PM, David Farler <dfarler@apple.com> wrote:

  Turn on dynamic super method dispatch by default

  This removes the -use-native-super-method flag and turns on dynamic
  dispatch for native method invocations on super by default.

  rdar://problem/22749732 <rdar://problem/22749732>

Random question: does this still use static dispatch when the superclass is within the same resilience domain, or is it the SIL optimizer’s job to handle that?

-Chris

In SILGen, when the method isn't final, it does always emits a super_method instruction, but Roman added devirtualizer support for these, and it does look like they are getting optimized down to static dispatch when the nearest implementation is in the same module.


(David Farler) #4

Actually it looks like it would be trivial to do it during SILGen, although looking at some generated code with TOT the devirtualizer is already kicking in for these at -Onone. Is there still a benefit from doing it earlier on?

David

···

On Jan 18, 2016, at 11:33 AM, Chris Lattner <clattner@apple.com> wrote:

On Jan 17, 2016, at 2:49 PM, David Farler <dfarler@apple.com <mailto:dfarler@apple.com>> wrote:

  Turn on dynamic super method dispatch by default

  This removes the -use-native-super-method flag and turns on dynamic
  dispatch for native method invocations on super by default.

  rdar://problem/22749732 <rdar://problem/22749732>

Random question: does this still use static dispatch when the superclass is within the same resilience domain, or is it the SIL optimizer’s job to handle that?

-Chris

In SILGen, when the method isn't final, it does always emits a super_method instruction, but Roman added devirtualizer support for these, and it does look like they are getting optimized down to static dispatch when the nearest implementation is in the same module.

Good news, thanks. Would it make sense for -O0 perf to have SILGen generate the static dispatch when possible, or is it too much trouble for the benefit?

-Chris


(Chris Lattner) #5

I don’t know if it is worth it in this case. The pro/con of doing this is usually:

1) Faster generated -O0 builds makes everyone happy.
2) Faster optimized compiles (by putting less pressure on the optimizer) makes people happy.
3) Earlier devirtualization can have unexpected knock-on effects by allowing early inlining and better IPA to happen.
4) more complexity in SILGen has a cost. If it requires major new infrastructure, then it is usually not worth it. If it drops in as a special case in an existing path, then it usually is.

I don’t know how the balance in this case works itself out, but both Clang IRGen and Swift SILGen (in other cases) try to avoid generating indirect calls when it is locally apparent they can be statically dispatched.

-Chris

···

On Jan 18, 2016, at 6:36 PM, David Farler <dfarler@apple.com> wrote:

In SILGen, when the method isn't final, it does always emits a super_method instruction, but Roman added devirtualizer support for these, and it does look like they are getting optimized down to static dispatch when the nearest implementation is in the same module.

Good news, thanks. Would it make sense for -O0 perf to have SILGen generate the static dispatch when possible, or is it too much trouble for the benefit?

-Chris

Actually it looks like it would be trivial to do it during SILGen, although looking at some generated code with TOT the devirtualizer is already kicking in for these at -Onone. Is there still a benefit from doing it earlier on?


(Mark Lacey) #6

FWIW the fact that these are getting devirtualized right now is a happy accident of making @_transparent work in more cases by devirtualizing in the mandatory inliner. I don’t expect that to be removed, but if we really want to guarantee direct calls in the trivial cases it’s worth considering adding support explicitly in SILGen, especially if it’s trivial to do.

Mark

···

On Jan 18, 2016, at 9:56 PM, Chris Lattner via swift-dev <swift-dev@swift.org> wrote:

On Jan 18, 2016, at 6:36 PM, David Farler <dfarler@apple.com> wrote:

In SILGen, when the method isn't final, it does always emits a super_method instruction, but Roman added devirtualizer support for these, and it does look like they are getting optimized down to static dispatch when the nearest implementation is in the same module.

Good news, thanks. Would it make sense for -O0 perf to have SILGen generate the static dispatch when possible, or is it too much trouble for the benefit?

-Chris

Actually it looks like it would be trivial to do it during SILGen, although looking at some generated code with TOT the devirtualizer is already kicking in for these at -Onone. Is there still a benefit from doing it earlier on?

I don’t know if it is worth it in this case. The pro/con of doing this is usually:

1) Faster generated -O0 builds makes everyone happy.
2) Faster optimized compiles (by putting less pressure on the optimizer) makes people happy.
3) Earlier devirtualization can have unexpected knock-on effects by allowing early inlining and better IPA to happen.
4) more complexity in SILGen has a cost. If it requires major new infrastructure, then it is usually not worth it. If it drops in as a special case in an existing path, then it usually is.

I don’t know how the balance in this case works itself out, but both Clang IRGen and Swift SILGen (in other cases) try to avoid generating indirect calls when it is locally apparent they can be statically dispatched.


(David Farler) #7

Interesting, I was just about to ask whether devirtualization was considered a mandatory optimization. So, it sounds like this is worth doing, it's a pretty lightweight check that I can drop into the two places where these are emitted. I think I have the patch - I'll run the tests and try to land it tomorrow. Thanks!

David

···

On Jan 18, 2016, at 22:19, Mark Lacey <mark.lacey@apple.com> wrote:

On Jan 18, 2016, at 9:56 PM, Chris Lattner via swift-dev <swift-dev@swift.org> wrote:

On Jan 18, 2016, at 6:36 PM, David Farler <dfarler@apple.com> wrote:

In SILGen, when the method isn't final, it does always emits a super_method instruction, but Roman added devirtualizer support for these, and it does look like they are getting optimized down to static dispatch when the nearest implementation is in the same module.

Good news, thanks. Would it make sense for -O0 perf to have SILGen generate the static dispatch when possible, or is it too much trouble for the benefit?

-Chris

Actually it looks like it would be trivial to do it during SILGen, although looking at some generated code with TOT the devirtualizer is already kicking in for these at -Onone. Is there still a benefit from doing it earlier on?

I don’t know if it is worth it in this case. The pro/con of doing this is usually:

1) Faster generated -O0 builds makes everyone happy.
2) Faster optimized compiles (by putting less pressure on the optimizer) makes people happy.
3) Earlier devirtualization can have unexpected knock-on effects by allowing early inlining and better IPA to happen.
4) more complexity in SILGen has a cost. If it requires major new infrastructure, then it is usually not worth it. If it drops in as a special case in an existing path, then it usually is.

I don’t know how the balance in this case works itself out, but both Clang IRGen and Swift SILGen (in other cases) try to avoid generating indirect calls when it is locally apparent they can be statically dispatched.

FWIW the fact that these are getting devirtualized right now is a happy accident of making @_transparent work in more cases by devirtualizing in the mandatory inliner. I don’t expect that to be removed, but if we really want to guarantee direct calls in the trivial cases it’s worth considering adding support explicitly in SILGen, especially if it’s trivial to do.

Mark