External symbols used to be stored in a DenseSet. An assert in
addExternalSymbol ensures that names of external symbols are unique.
However, for objects containing a huge number of external symbols, this
assert can be a performance bottleneck.
This patch proposes to store external symbols in a StringMap instead
making it significantly cheaper to check if a certain symbol name
already exists.
This issue came up while porting BOLT to JITLink (D147544): linking a
large binary using the JITLink port turned out to be about 4x slower
than the current version of BOLT that uses RuntimeDyld. This slowdown
was caused entirely by the assert in addExternalSymbol. Using this
patch, the JITLink port is slightly faster than RuntimeDyld.
Note that I fully understand that adding complexity to improve the
performance of an assert might not be acceptable (since the checks
shouldn't exist in release builds). This patch has another advantage,
however: since external symbol names really have to be unique, it could
make sense to make this clear at the type level.