Let me prefix this reply by admitting that I'm not a power user of interpolation, so this is mostly speculation/imagination...
I was thinking that one of the motivations for this design was to decouple the conformance implementations from the actual compiler-generated code.
One example of where the literalCount could be useful might be:
let combined = "\(prefix)\(middle)\(suffix)"
In this case, there's no need to generate any calls to appendLiteral(). In a hypothetical conformance that stores the literal segments in an array, it might be helpful to know that there will not be any.
Another interesting case would be allowing the compiler to split literal segments (that is, call appendLiteral() more than once in a row). For example:
let mixed = "👍 Nice work, \(name)"
Here, it might be more efficient to split the literal into an emoji-containing segment ("👍") and a pure-ASCII segment (" Nice work, ").
A related example would be a literal that just barely crosses an exponential growth boundary, like:
let longString = "Pretend this segment contains 257 characters. \(name)"
Here, maybe it could be more efficient to split the literal into a 256-character string, and a 1-character string. (Although I would guess that statically-declared strings might allocate space more exactly.)
Ah, yeah, this is a good example.
It still suffers from the problem that reserveCapacity(totalLiteralSize + interpolationCount * 2) isn't correct for literals that contain non-ASCII content, though.
Maybe the answer is ... more context! 
protocol StringInterpolationProtocol {
init(context: StringInterpolationContext)
}
struct StringInterpolationContext {
var literalCount: Int
var interpolationCount: Int
var isASCIILiteral: Bool
var totalLiteralUTF8Count: Int
var totalLiteralUTF16Count: Int
var totalLiteralUnicodeScalarCount: Int
}
Of course, there's no way to know whether the interpolated values will contain non-ASCII characters, so maybe that's not so useful.