<div dir="ltr"><div style="font-size:12.8px"><div>Hi,</div><div><br></div><div>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?</div><div><br></div><div><div style="font-size:12.8px"><b>Original code:</b></div></div><div><b><br></b></div><div><br></div><div>protocol SumProtocol: class {</div><div>  func increment(i:Int)  -&gt; Int</div><div>}</div><div><br></div><div>internal class SumClass: SumProtocol {</div><div>  var a:Int</div><div>  init(base:Int) {</div><div>    self.a = base</div><div>  }</div><div>  func increment(i:Int) -&gt; Int {</div><div>   self.a += i</div><div>   return self.a</div><div>  }</div><div>}</div><div><br></div><div>@inline(never) internal func wrap_inc(a:SumProtocol, val:Int) -&gt; Int{</div><div> return a.increment(i:val)</div><div>}</div><div><br></div><div>internal let magic:SumProtocol = SumClass(base:10)</div><div>print(&quot;c=\(wrap_inc(a:magic,<wbr>val:10))&quot;)</div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><b>After Step 1:</b></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><div>protocol SumProtocol: class {</div><div>  func increment(i:Int)  -&gt; Int</div><div>}</div><div><br></div><div>internal class SumClass: SumProtocol {</div><div>  var a:Int</div><div>  init(base:Int) {</div><div>    self.a = base</div><div>  }</div><div>  func increment(i:Int) -&gt; Int {</div><div>   self.a += i</div><div>   return self.a</div><div>  }</div><div>}</div><div><br></div><div><div style="font-size:12.8px">@inline(never) internal func wrap_inc(a:SumProtocol, val:Int) -&gt; Int{</div><div style="font-size:12.8px"> return a.increment(i:val)</div><div style="font-size:12.8px">}</div></div><div><br></div><div>@inline(never) internal func wrap_inc_1(a:SumClass, val:Int) -&gt; Int{</div><div> return a.increment(i:val)</div><div>}</div><div><br></div><div>internal let magic:SumClass = SumClass(base:10)</div><div>print(&quot;c=\(wrap_inc_1(a:magic,<wbr>val:10))&quot;)</div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px"><div><b>After Step 2:</b></div><div><b><br></b></div><div><div>internal class SumClass {</div><div>  var a:Int</div><div>  init(base:Int) {</div><div>    self.a = base</div><div>  }</div><div>  func increment(i:Int) -&gt; Int {</div><div>   self.a += i</div><div>   return self.a</div><div>  }</div><div>}</div><div><br></div><div>@inline(never) <span style="font-size:12.8px">internal </span><span style="font-size:12.8px">func wrap_inc(a:SumClass, val:Int) -&gt; Int{</span></div><div> return a.increment(i:val)</div><div>}</div><div><br></div><div>internal let magic:SumClass = SumClass(base:10)</div><div>print(&quot;c=\(wrap_inc(a:magic,<wbr>val:10))&quot;)</div></div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Any comments/thought on this transformation?</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Best,</div><div style="font-size:12.8px">Raj </div></div>