What is the preferred way to declare a type parameter of a function?

I’ve tried to generate intermediate SIL code and LLVM IR code based on this great post:

Source:

protocol P {}
func foo<T: P>(_ type: T.Type) {}

protocol P {}
func foo(_ type: P.Type) {}

SIL:

// foo<A>(_:)
sil hidden @$S3one3fooyyxmAA1PRzlF : $@convention(thin) <T where T : P> (@thick T.Type) -> () {
// %0                                             // user: %1
bb0(%0 : $@thick T.Type):
  debug_value %0 : $@thick T.Type, let, name "type", argno 1 // id: %1
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function '$S3one3fooyyxmAA1PRzlF'

// foo(_:)
sil hidden @$S3one3fooyyAA1P_pXpF : $@convention(thin) (@thick P.Type) -> () {
// %0                                             // user: %1
bb0(%0 : $@thick P.Type):
  debug_value %0 : $@thick P.Type, let, name "type", argno 1 // id: %1
  %2 = tuple ()                                   // user: %3
  return %2 : $()                                 // id: %3
} // end sil function '$S3one3fooyyAA1P_pXpF'

And the LLVM IR:

// foo<T>(_:)
define hidden swiftcc void @"$S3one3fooyyxmAA1PRzlF"(%swift.type*, %swift.type* %T, i8** %T.P) #0 {
entry:
  ret void
}

// foo(_:)
define hidden swiftcc void @"$S3one3fooyyAA1P_pXpF"(%swift.type*, i8**) #0 {
entry:
  ret void
}

The result is that this is all fine & nerdy, but I still don’t know the answer.