[swift-dev] Protocol Devirtualizer Pass

Raj Barik rkbarik at gmail.com
Wed Nov 29 13:30:20 CST 2017


Hi,

I am thinking about writing a Protocol Devirtualizer Pass that specializes
functions that take Protocols as arguments to transform them with concrete
types instead of protocol types when the concrete types can be determined
statically by some compiler analysis. This is the first step of the
transformation that I am proposing. My goal is to extend this to eliminate
the original function implementation and also to remove the corresponding
protocol type (by deleting it from the witness table), if possible. For
simple cases, where the protocol is only used for mocking for example and
that there is just one class that conforms to it, we should be able to
eliminate the protocol altogether. This is the second and final step of the
transformation. Does anyone see any issues with both these steps? Arnold
from Apple pointed out that there might be demangling issues when the
protocol is eliminated. Any ideas on how to fix the demangling issues?
Moreover, would such a pass be helpful to Swift folks?

*Original code:*


protocol SumProtocol: class {
  func increment(i:Int)  -> Int
}

internal class SumClass: SumProtocol {
  var a:Int
  init(base:Int) {
    self.a = base
  }
  func increment(i:Int) -> Int {
   self.a += i
   return self.a
  }
}

@inline(never) internal func wrap_inc(a:SumProtocol, val:Int) -> Int{
 return a.increment(i:val)
}

internal let magic:SumProtocol = SumClass(base:10)
print("c=\(wrap_inc(a:magic,val:10))")


*After Step 1:*


protocol SumProtocol: class {
  func increment(i:Int)  -> Int
}

internal class SumClass: SumProtocol {
  var a:Int
  init(base:Int) {
    self.a = base
  }
  func increment(i:Int) -> Int {
   self.a += i
   return self.a
  }
}

@inline(never) internal func wrap_inc(a:SumProtocol, val:Int) -> Int{
 return a.increment(i:val)
}

@inline(never) internal func wrap_inc_1(a:SumClass, val:Int) -> Int{
 return a.increment(i:val)
}

internal let magic:SumClass = SumClass(base:10)
print("c=\(wrap_inc_1(a:magic,val:10))")


*After Step 2:*

internal class SumClass {
  var a:Int
  init(base:Int) {
    self.a = base
  }
  func increment(i:Int) -> Int {
   self.a += i
   return self.a
  }
}

@inline(never) internal func wrap_inc(a:SumClass, val:Int) -> Int{
 return a.increment(i:val)
}

internal let magic:SumClass = SumClass(base:10)
print("c=\(wrap_inc(a:magic,val:10))")

Any comments/thought on this transformation?

Best,
Raj
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20171129/e130dad8/attachment.html>


More information about the swift-dev mailing list