LLVM, el compilador de Clang, ha introducido una optimización en SmallVector::push_back para tipos aproximadamente copiables triviales, su operación más caliente. Antes, la ruta rápida del push_back reservaba capacidad, almacenaba el elemento y luego llamaba a grow_pod, lo que obligaba a guardar this y el elemento en registros callee-saved y generaba un frame de pila con push rbp/push rbx solo para sobrevivir a la llamada. Shrink-wrapping no podía eliminarlo y GCC no lo hacía mejor.
La solución, en el pull request #206213, mueve el crecimiento y el almacenamiento a una función externa growAndPushBack marcada con noinline y la invoca con tail call. El resultado: la ruta rápida pasa de 14 instrucciones a 7, sin registros callee-saved y sin frame. En lld, el segmento .text se reduce 40 512 bytes; el clang compilado ejecuta entre un 0,41 % y un 0,51 % menos de instrucciones, a costa de un 0,13 % más de binario. Casos como GotSection::addConstant bajan de 167 a 45 bytes. Noinline es indispensable: sin él, Clang y GCC vuelven a-inlinealizar.
El artículo compara con std::vector de libc++ y libstdc++, y con boost::small_vector y absl::InlinedVector, que también mantienen un frame en la ruta rápida. SmallVector sacrifica 8 bytes en para evitar ramas is_allocated en el camino caliente. La pega: en bucles de push_back el diseño con tail-call pierde rendimiento, porque &v escapa y los campos se releen cada iteración. Por eso, un bucle intensivo prefiere std::vector, cuyo crecimiento inlineado mantiene end/cap en registros.
