Copyright
Copyright © José Luis Lara Carrascal 2012-2023 
Sumario
Introducción
Instalación
Configurar el sistema para el uso de Clang
Optimizaciones de CPU para Clang
Niveles de optimización soportados por Clang
Optimizaciones adicionales para Clang
LLD - El enlazador dinámico de LLVM
Libc++ - La librería estándar de C++ de LLVM
Comparativa de resultados de optimización entre Clang y GCC
Enlaces
Introducción
Clang es un software creado para proveer al compilador LLVM de una interfaz para poder compilar código escrito en C, C++, Objective C y Objective C++. Compatible con GCC,
es más rápido y utiliza menos memoria que este
último, aunque no soporta de momento, todas las
características de GCC. En este manual trataremos su instalación y la de LLVM, además de explicar la forma de configurar el sistema para su uso, y las diferencias respecto a GCC,
en lo que concierne a las optimizaciones de procesador. A partir de la
publicación de este manual, todos los manuales de la web que
sean compatibles con Clang,
incluirán la correspondiente información para su uso,
tomando como referencia la instalación tratada en este manual.
Desde el 2 de mayo de 2018, el manual se ha actualizado a una
instalación en un sistema de 64 bits multiarquitectura.
Instalación
Dependencias
Herramientas de Compilación
Entre paréntesis la versión con la que se ha compilado Clang para la elaboración de este documento.
* GCC - (13.2.0) o Clang - (17.0.5)
* CMake - (3.27.8)
* Ninja - (1.11.1)
* Pkg-config - (0.29.2)
Librerías de Desarrollo
* GNU Binutils - (2.41)
* Elfutils - (0.190)
* Libffi - (3.4.4)
* Libxml2 - (2.11.6)
* Ncurses - (6.4)
* SPIRV-Tools - (2023.2)
* Zlib - (1.3)
Intérpretes de Lenguaje de Programación
* Perl - (5.38.0)
* Python - (3.12.0)
Pygments - (2.16.1)
PyYAML - (6.0.1)
Aplicaciones
* Sphinx - (7.2.6)
Descarga
llvm-17.0.6.tar.xz
Firma Digital 
llvm-17.0.6.tar.xz.asc
Verificar la firma digital del paquete
$ gpg --import manualinux.asc
$ gpg --verify llvm-17.0.6.tar.xz.asc llvm-17.0.6.tar.xz
|
Optimizaciones
$ export {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3'
|
Donde pone znver3 se indica el procesador respectivo de cada sistema seleccionándolo de la siguiente tabla: |
Nota informativa sobre las optimizaciones para GCC
|
* La opción '-march=' establece el procesador mínimo con el que funcionará el programa compilado, la opción '-mtune=' el procesador específico para el que será optimizado.
* Los valores separados por comas, son equivalentes, es decir, que lo mismo da poner '-march=k8' que '-march=athlon64'.
* En versiones de GCC 3.2 e inferiores se utiliza la opción '-mcpu=' en lugar de '-mtune='.
|
Nota informativa sobre las optimizaciones para Clang
|
* La opción '-mtune=' está soportada a partir de la versión 3.4 de Clang.
* Los valores de color azul no son compatibles con Clang.
* Las filas con el fondo de color amarillo son valores exclusivos de Clang y, por lo tanto, no son aplicables con GCC.
|
Valores |
CPU |
Genéricos |
generic |
Produce un código binario
optimizado para la mayor parte de procesadores existentes. Utilizar
este valor si no sabemos el nombre del procesador que tenemos en
nuestro equipo. Este valor sólo es aplicable en la opción
'-mtune=', si utilizamos GCC. Esta opción está disponible a partir de GCC 4.2. |
native |
Produce un código binario
optimizado para el procesador que tengamos en nuestro sistema, siendo
éste detectado utilizando la instrucción cpuid.
Procesadores antiguos pueden no ser detectados utilizando este valor.
Esta opción está disponible a partir de GCC 4.2. |
x86-64 |
Procesador genérico con extensiones 64-bit. Esta opción está disponible a partir de GCC 8 y Clang 1.9. |
x86-64-v2 |
Procesador genérico con con
soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT,
SSE3, SSE4.1, SSE4.2, SSSE3) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
x86-64-v3 |
Procesador genérico con con
soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT,
SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C, FMA, LZCNT, MOVBE, XSAVE,
XSAVEC, FMA4) y extensiones 64-bit. Esta opción está
disponible a partir de GCC 11 y Clang 12. |
x86-64-v4 |
Procesador genérico con con
soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT,
SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C, FMA, LZCNT, MOVBE, XSAVE,
XSAVEC, AVX512*, FMA4) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
Intel |
alderlake |
Intel Alderlake con soporte de
instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI,
AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE,
PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE,
AMX-INT8, AVX-VNNI) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
atom |
Intel Atom con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y extensiones
64-bit. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición bonnell. |
bonnell |
Intel Bonnell con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3 y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9. |
broadwell |
Intel Broadwell con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW y extensiones 64-bit. Esta opción
está disponible a partir de GCC 4.9 y Clang 3.6. |
cannonlake |
Intel Cannonlake Server con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA,
UMIP y extensiones 64-bit. Esta opción está
disponible a partir de GCC 8 y Clang 3.9. |
cascadelake |
Intel Cascadelake con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI y extensiones
64-bit. Esta opción está disponible a partir de GCC 9 y Clang 8. |
cooperlake |
Intel Cooper
Lake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VNNI, AVX512BF16 y extensiones 64-bit. Esta opción
está disponible a partir de GCC 10 y Clang 9. |
core2 |
Intel Core2 con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y extensiones 64-bit. Esta
opción está disponible a partir de GCC 4.3. |
core-avx2 |
Intel Core (Haswell). Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición haswell. |
core-avx-i |
Intel Core (ivyBridge)
con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, AVX, AES, PCLMUL, FSGSBASE, RDRND, F16C y extensiones
64-bit. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición ivybridge. |
corei7 |
Intel Core i7 con soporte
de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 y SSE4.2 y
extensiones 64-bit. Soporta también los procesadores Intel Core
i3 e i5. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición nehalem. |
corei7-avx |
Intel Core i7 con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AES y
PCLMUL y extensiones 64-bit. Soporta también los procesadores
Intel Core i3 e i5. Esta opción está disponible
desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición sandybridge. |
emeraldrapids |
Intel Emerald Rapids. Esta opción está disponible a partir de GCC 13 y Clang 16. |
goldmont |
Intel Goldmont con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE y extensiones
64-bit. Esta opción está disponible a partir de GCC 9 y Clang 5. |
goldmont-plus |
Intel Goldmont Plus con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE, RDPID,
SGX, UMIP y extensiones 64-bit. Esta opción está
disponible a partir de GCC 9 y Clang 7. |
grandridge |
Intel Grand Ridge con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES, XSAVEOPT,
FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI, MOVDIR64B,
CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT,
PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, RAOINT y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 13 y Clang 16. |
graniterapids |
Intel Grand Ridge con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, RDRND, F16C,
AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, AES,
CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ,
AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES,
AVX512VBMI2, VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG,
WBNOINVD, CLWB, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD,
CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16,
AMX-TILE, AMX-INT8, AVX-VNNI, AVX512-FP16, AVX512BF16, AMX-FP16,
PREFETCHI y extensiones 64-bit. Esta opción está
disponible a partir de GCC 13 y Clang 16. |
graniterapids-d |
Intel Xeon Granite Rapids-D. Esta opción está
disponible a partir de Clang 17. |
haswell |
Intel Haswell con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 4.9. |
i386 |
Intel i386.
|
i486 |
Intel i486. |
i586, pentium |
Intel Pentium sin soporte de instrucciones MMX. |
i686 |
Produce un código binario
optimizado para la mayor parte de procesadores compatibles con la serie
80686 de Intel. Todos los actuales lo son. |
icelake-client |
Intel Icelake Client con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA,
CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG,
AVX512VNNI, VPCLMULQDQ, VAES y extensiones 64-bit. Esta
opción está disponible a partir de GCC 8 y Clang 7. |
icelake-server |
Intel Icelake Server con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA,
CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG,
AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG, WBNOINVD y extensiones
64-bit. Esta opción está disponible a partir de GCC 8 y Clang 7. |
intel |
Intel Haswell y Silvermont. Este
valor sólo es aplicable en la opción '-mtune='. Esta
opción está disponible a partir de GCC 4.9. |
ivybridge |
Intel Ivy Bridge con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX,
AES, PCLMUL, FSGSBASE, RDRND, F16C y extensiones 64-bit. Esta
opción está disponible a partir de GCC 4.9. |
knl |
Intel Knights Landing con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW, AVX512F, AVX512PF, AVX512ER y extensiones
64-bit. Esta opción está disponible a partir de GCC 5 y Clang 3.4. |
knm |
Intel Knights Mill con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW, AVX512F, AVX512PF, AVX512ER, AVX512CD,
AVX5124VNNIW, AVX5124FMAPS, AVX512VPOPCNTDQ y extensiones 64-bit. Esta
opción está disponible a partir de GCC 8 y Clang 6. |
lakemont |
Intel Quark Lakemont MCU, basado en el procesador Intel Pentium. Esta opción está disponible a partir de GCC 6 y Clang 3.9. |
meteorlake |
Intel Meteor Lake. Esta opción está disponible a partir de GCC 13 y Clang 16. |
nehalem |
Intel Nehalem con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 4.9. |
nocona |
Versión mejorada de Intel Pentium4 con soporte de instrucciones MMX, SSE, SSE2, SSE3 y extensiones 64-bit. |
penryn |
Intel Penryn con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y SSE4.1. |
pentiumpro |
Intel PentiumPro. |
pentium2 |
Intel Pentium2 basado en PentiumPro con soporte de instrucciones MMX. |
pentium3, pentium3m |
Intel Pentium3 basado en PentiumPro con soporte de instrucciones MMX y SSE. |
pentium4, pentium4m |
Intel Pentium4 con soporte de instrucciones MMX, SSE y SSE2. |
pentium-m |
Versión de bajo consumo de
Intel Pentium3 con soporte de instrucciones MMX, SSE y SSE2. Utilizado
por los portátiles Centrino. |
pentium-mmx |
Intel PentiumMMX basado en Pentium con soporte de instrucciones MMX. |
prescott |
Versión mejorada de Intel Pentium4 con soporte de instrucciones MMX, SSE, SSE2 y SSE3. |
raptorlake |
Intel Raptor Lake. Esta opción está disponible a partir de GCC 13 y Clang 16. |
rocketlake |
Intel Rocket Lake con soporte de
instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 11 y Clang 13. |
sandybridge |
Intel Sandy Bridge con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX,
AES, PCLMUL y extensiones 64-bit. Esta opción está
disponible a partir de GCC 4.9 y Clang 3.6. |
sapphirerapids |
Intel Sapphire Rapids con soporte
de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI,
AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE,
PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE,
AMX-INT8 and AVX-VNNI) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
silvermont |
Intel Silvermont con soporte de
instrucciones MOVBE, MMX, SSE, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, AES, PCLMU, RDRND y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9 y Clang 3.6. |
sierraforest |
Intel Sierra Forest con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES, XSAVEOPT,
FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI, MOVDIR64B,
CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT,
PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD y extensiones
64-bit. Esta opción está disponible a partir de GCC 13 y Clang 16. |
skylake |
Intel Skylake con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES y extensiones
64-bit. Esta opción está disponible a partir de GCC 6 y Clang 3.6. |
skylake-avx512 |
Intel Skylake Server con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL,
AVX512BW, AVX512DQ, AVX512CD y extensiones 64-bit. Esta opción
está disponible a partir de GCC 6 y Clang 3.9. |
tigerlake |
Intel Tiger Lake
con soporte de instrucciones OVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG, WBNOINVD, MOVDIRI,
MOVDIR64B, AVX512VP2INTERSECT y extensiones 64-bit. Esta opción
está disponible a partir de GCC 10 y Clang 10. |
tremont |
Intel Tremont con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE, RDPID,
SGX, UMIP, GFNI-SSE, CLWB, ENCLV y extensiones 64-bit. Esta
opción está disponible a partir de GCC 9 y Clang 7. |
westmere |
Intel Westmere con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES,
PCLMUL y extensiones 64-bit. Esta opción está
disponible a partir de GCC 4.9. |
yonah |
Procesadores basados en la microarquitectura de Pentium M, con soporte de instrucciones MMX, SSE, SSE2 y SSE3. |
AMD |
amdfam10, barcelona |
Procesadores basados en AMD Family
10h core con soporte de instrucciones x86-64 (MMX, SSE, SSE2, SSE3,
SSE4A, 3DNow!, enhanced 3DNow!, ABM y extensiones 64-bit). Esta
opción está disponible a partir de GCC 4.3. La definición barcelona está disponible a partir de Clang 3.6. |
athlon, athlon-tbird |
AMD Athlon con soporte de instrucciones MMX, 3DNow!, enhanced 3DNow! y SSE prefetch. |
athlon4, athlon-xp, athlon-mp |
Versiones mejoradas de AMD Athlon con soporte de instrucciones MMX, 3DNow!, enhanced 3DNow! y full SSE. |
bdver1 |
Procesadores basados en AMD Family
15h core con soporte de instrucciones x86-64 (FMA4, AVX, XOP, LWP, AES,
PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM
y extensiones 64-bit). Esta opción está disponible a
partir de GCC 4.7. |
bdver2 |
Procesadores basados en AMD Family
15h core con soporte de instrucciones x86-64 (BMI, TBM, F16C, FMA, LWP,
AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.7. |
bdver3 |
Procesadores basados en AMD Family
15h core con soporte de instrucciones x86-64 (FMA4, AVX, XOP, LWP, AES,
PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM
y extensiones 64-bit). Esta opción está disponible a
partir de GCC 4.8 y Clang 3.4. |
bdver4 |
Procesadores basados en AMD Family
15h core con soporte de instrucciones x86-64 (BMI, BMI2, TBM, F16C,
FMA, FMA4, FSGSBASE, AVX, AVX2, XOP, LWP, AES, PCL_MUL, CX16, MOVBE,
MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM y extensiones
64-bit). Esta opción está disponible a partir de GCC 4.9 y Clang 3.5. |
btver1 |
Procesadores basados en AMD Family
14h core con soporte de instrucciones x86-64 (MMX, SSE, SSE2, SSE3,
SSE4A, CX16, ABM y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.6. |
btver2 |
Procesadores basados en AMD Family
16h core con soporte de instrucciones x86-64 (MOVBE, F16C, BMI, AVX,
PCL_MUL, AES, SSE4.2, SSE4.1, CX16, ABM, SSE4A, SSSE3, SSE3, SSE2, SSE,
MMX y extensiones 64-bit). Esta opción está
disponible a partir de GCC 4.8. |
geode |
AMD integrado con soporte de instrucciones MMX y 3DNow!. Esta opción está disponible a partir de GCC 4.3. |
k6 |
AMD K6 con soporte de instrucciones MMX. |
k6-2, k6-3 |
Versiones mejoradas de AMD K6 con soporte de instrucciones MMX y 3DNow!. |
k8, opteron, athlon64, athlon-fx |
Procesadores basados en AMD K8 core
con soporte de instrucciones x86-64 (MMX, SSE, SSE2, 3DNow!, enhanced
3DNow! y extensiones 64-bit). |
k8-sse3, opteron-sse3, athlon64-sse3 |
Versiones mejoradas de AMD K8 core
con soporte de instrucciones SSE3. Esta opción está
disponible a partir de GCC 4.3. |
znver1 |
Procesadores basados en AMD Family
17h core con soporte de instrucciones x86-64 (BMI, BMI2, F16C, FMA,
FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES, PCL_MUL,
CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM,
XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y extensiones 64-bit). Esta
opción está disponible a partir de GCC 6 y Clang 4. |
znver2 |
Procesadores basados en AMD Family
17h core con soporte de instrucciones x86-64 (BMI, BMI2, ,CLWB, F16C,
FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES,
PCL_MUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1,
SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y extensiones
64-bit). Esta opción está disponible a partir de GCC 9 y Clang 9. |
znver3 |
Procesadores basados en AMD Family
19h core con soporte de instrucciones x86-64 (BMI, BMI2, CLWB, F16C,
FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES,
PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1,
SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID, WBNOINVD, PKU,
VPCLMULQDQ, VAES) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
znver4 |
Procesadores basados en AMD Family
19h core con soporte de instrucciones x86-64 (BMI, BMI2, CLWB, F16C,
FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES,
PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1,
SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID, WBNOINVD, PKU,
VPCLMULQDQ, VAES, AVX512F, AVX512DQ, AVX512IFMA, AVX512CD, AVX512BW,
AVX512VL, AVX512BF16, AVX512VBMI, AVX512VBMI2, AVX512VNNI,
AVX512BITALG, AVX512VPOPCNTDQ, GFNI) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 12.3 y Clang 16. |
Optimizaciones adicionales
Optimizaciones adicionales |
GCC |
Graphite
|
$ export {C,CXX}FLAGS+=' -floop-interchange -ftree-loop-distribution -floop-strip-mine -floop-block' |
Clang |
Polly |
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine' |
Parámetros adicionales para la versión de 32 bits
Optimizaciones de CPU para Intel en sistemas de 64 bits multiarquitectura |
$ export {C,CXX}FLAGS='-O3 -march=i686 -mtune=pentium4' |
Optimizaciones de CPU para AMD en sistemas de 64 bits multiarquitectura |
$ export {C,CXX}FLAGS='-O3 -march=i686 -mtune=athlon-xp' |
Establecer la variable de entorno adecuada para pkg-config en sistemas de 64 bits multiarquitectura |
$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/share/pkgconfig:$PKG_CONFIG_PATH |
Establecer la ruta de búsqueda de directorios de librerías en sistemas de 64 bits multiarquitectura |
$ export LDFLAGS+=' -L/usr/lib -L/usr/local/lib -L/opt/gcc13/lib' |
Establecer
la variable de entorno de arquitectura de procesador requerida en
sistemas de 64 bits multiarquitectura basados en el CLFS |
$ export USE_ARCH=32 |
Establecer la variable de entorno de uso de compilador en modo de 32 bits, en sistemas de 64 bits multiarquitectura |
GCC |
$ export CC="gcc -m32" CXX="g++ -m32"
|
Clang |
$ export CC="clang -m32" CXX="clang++ -m32"
|
Parámetros adicionales para la versión de 64 bits
Establecer la variable de entorno de uso de compilador para Clang |
$ export CC=clang CXX=clang++
|
Parámetros adicionales globales
Parámetros adicionales de eliminación de avisos en el proceso de compilación |
$ export {C,CXX}FLAGS+=' -w' |
Parámetros adicionales complementarios de la optimización LTO/ThinLTO |
GCC |
$ export AR=gcc-ar RANLIB=gcc-ranlib NM=gcc-nm |
Establecer el uso de enlazador dinámico para LLD |
Clang |
$ export LDFLAGS+=' -fuse-ld=lld' |
Optimizaciones complementarias LTO/ThinLTO de LLD |
$ export LDFLAGS+=' -Wl,--lto-aa-pipeline=globals-aa -Wl,--lto-newpm-passes=memcpyopt' |
Optimizaciones complementarias LTO de LLD |
$ export LDFLAGS+=" -Wl,--lto-partitions=$(expr
$(nproc) / 2)" |
Optimizaciones complementarias ThinLTO de LLD |
$ export LDFLAGS+=" -Wl,--thinlto-jobs=$(expr
$(nproc) / 2)" |
Extracción 
$ tar Jxvf llvm-17.0.6.tar.xz
$ cd llvm-17.0.6
|
1) Configuración de la versión de 32 bits
2) Configuración de la versión de 64 bits estática
3) Configuración de la versión de 64 bits compartida
1) Configuración de la versión de 32 bits
La compilación de la versión de 32 bits de LLVM
sólo es necesaria si tenemos pensado compilar la versión
de 32 bits de Mesa con
soporte de LLVM, o somos usuarios de una tarjeta gráfica de AMD
como es mi caso y tenemos que hacer uso del controlador de
gráficos, AMDGPU. A diferencia de GCC, LLVM no compila las
librerías de 32 bits en el mismo proceso de compilación,
en un sistema de 64 bits multiarquitectura.
$ mkdir build32; cd build32
$ cmake -DLLVM_ENABLE_PROJECTS="clang;polly"-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/llvm17 -DLLVM_TARGETS_TO_BUILD="X86;AMDGPU;BPF" \
-DBUILD_SHARED_LIBS=ON -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_FFI=ON \
-DOCAMLFIND=null -DCLANG_BUILD_TOOLS=OFF -DLLVM_ENABLE_DUMP=ON \
-DLLVM_SPIRV_INCLUDE_TESTS=OFF -G Ninja ../llvm |
Explicación de los comandos
mkdir build32; cd build32 : Crea
un directorio de compilación para no compilar directamente en el
directorio de las fuentes, y entramos en el mismo.
-DLLVM_ENABLE_PROJECTS="clang;polly":
Activa la compilación de los proyectos clang y polly,
requeridos para poder compilar el soporte de OpenCL en
Mesa, de las tarjetas gráficas de AMD, utilizando el
controlador Clover de Gallium.
-DCMAKE_BUILD_TYPE=Release : Compila la versión optimizada de LLVM.
-DCMAKE_INSTALL_PREFIX=/opt/llvm17 : Instala LLVM en /opt/llvm17.
-DLLVM_TARGETS_TO_BUILD="X86;AMDGDPU;BPF" : Compila sólo el soporte de la arquitectura de procesador x86, el soporte del controlador de gráficos de código abierto, AMDGPU (requerido para poder compilar Mesa con soporte de las tarjetas gráficas de AMD) y el soporte de BPF, requerido para la compilación del paquete v4l-utils, omitiendo otras como ARM, PowerPC, etc. Esto reduce el tiempo de
compilación y el tamaño del directorio de
instalación del compilador.
-DBUILD_SHARED_LIBS=ON : Compila las librerías compartidas en lugar de las estáticas.
-DLLVM_ENABLE_RTTI=ON : Parámetro requerido para poder compilar Mesa con soporte de LLVM con el sistema de compilación, Meson.
-DLLVM_ENABLE_FFI=ON : Activa el soporte de Libffi, librería de características similares a GMP.
-DOCAMLFIND=null : Al no tener el paquete una opción específica para desactivar la adaptación de LLVM para el lenguaje de programación OCaml, le indicamos una ruta nula al ejecutable ocamlfind,
para poder desactivar el soporte de esta dependencia. Si no tenemos
instalado OCaml en nuestro sistema, esto no hay que añadirlo.
-DLLVM_CCACHE_BUILD=ON : Activa el uso de Ccache para compilar el paquete.
-DCLANG_BUILD_TOOLS=OFF
: Desactiva la compilación del binario ejecutable de Clang, ya
que sólo necesitaremos las librerías para poder compilar
el soporte de OpenCL en Mesa, de las tarjetas gráficas de AMD,
utilizando el controlador Clover de Gallium.
-DLLVM_ENABLE_DUMP=ON : Requerido para poder compilar el soporte del experimental controlador gallium-rusticl de las librerías Mesa.
-DLLVM_SPIRV_INCLUDE_TESTS=OFF : Omite la compilación de los tests de SPIRV-LLVM-Translator.
-G Ninja : Utiliza Ninja en lugar de GNU Make para compilar el paquete (opcional).
Parámetros de configuración opcionales
-DLLVM_CCACHE_BUILD=ON : Activa el uso de Ccache
en el proceso de compilación. Si tenemos configurado Ccache con
los correspondientes enlaces simbólicos, no es necesario
añadir esta opción. Pero sí tenemos que tener activadas las opciones de Ccache, hash_dir y run_second_cpp, que vienen activadas por defecto.
-DCMAKE_AR=$(which $AR) -DCMAKE_RANLIB=$(which $RANLIB) -DCMAKE_NM=$(which $NM) : Sincroniza las variables de entorno establecidas en el manual, relativas a los binarios ejecutables intermedios, gcc-ar, gcc-ranlib y gcc-nm, con los parámetros de configuración utilizados por CMake, relativos a los programas ar, ranlib y nm, para poder aplicar correctamente la optimización LTO.
Se utiliza el comando which para buscar los ejecutables porque desde
hace ya varias versiones, CMake no establece correctamente la ruta al
ejecutable en cuestión. Esto no es necesario hacerlo, si
compilamos el paquete con Clang.
-DLLVM_ENABLE_LTO=ON|Thin : Activa el uso de la optimización LTO,
tanto con GCC como con Clang, siempre en combinación con el
parámetro anteriormente descrito. Si vamos a utilizar Clang, muy
recomendable hacer uso de ThinLTO en lugar de LTO, estableciendo Thin en lugar de ON, en el valor de este parámetro, para reducir el tiempo de compilación del paquete.
-DLLVM_ENABLE_LLD=ON
: Este parámetro sólo es necesario si utilizamos la
optimización ThinLTO con Clang, y no tenemos configurado un
directorio caché para LLD en nuestro sistema, cuyo uso hemos
establecido con la correspondiente variable de entorno de uso de
enlazador dinámico para LLD. El proceso de configuración
creará uno en la raíz del directorio de
compilación con el nombre lto.cache
y almacenará en el mismo los archivos objeto que se generen en
el proceso de enlazado, evitando utilizar la memoria física del
sistema, si tenemos montado el directorio /tmp con el sistema de archivos, Tmpfs.
Si se establece LLD como enlazador dinámico, antes del comando
de configuración del paquete, esta opción no será
funcional.
-DLLVM_PARALLEL_LINK_JOBS=$(nproc)
: Establece el número de procesos en paralelo de enlazado (por
defecto es 2), tomando como referencia la información del
número de núcleos de nuestro procesador, proporcionada
por el sistema. Este parámetro sólo es aplicable con Ninja. Si compilamos el paquete con Clang, estableciendo las correspondientes
variables de entorno de LLD de este manual, es recomendable no utilizar esta opción.
-DCMAKE_STRIP=/usr/bin/strip : Sustituye llvm-strip por strip,
en el caso de que compilemos el paquete con Clang. El segundo es
bastante mejor que el primero, a la hora de reducir el tamaño de
los binarios compilados.
Compilación
Parámetros de compilación opcionales
-v : Muestra más información en el proceso de compilación.
-j$(nproc)
: Establece el número de procesos de compilación en
paralelo, en función del número de núcleos e hilos
que tenga nuestro procesador, tomando como referencia la
información mostrada por el sistema con el comando
correspondiente. Si nuestro procesador es mononúcleo de un solo
hilo, no añadir esta opción.
Instalación como root de la versión de 32 bits
$ su
# ninja install/strip
# mv /opt/llvm17/bin/llvm-config{,-32}
# exit
$ cd ..
|
Explicación de los comandos
mv /opt/llvm17/bin/llvm-config{,-32}
: Renombramos el ejecutable encargado de mostrar la
información sobre la ubicación de las librerías de
LLVM en los procesos de compilación en los que sea necesario su
uso, siguiendo el método utilizado por el CLFS.
2) Configuración de la versión de 64 bits estática
$ mkdir build64; cd build64
$ cmake -DLLVM_ENABLE_PROYECTS="clang;lld;polly;compiler-rt;openmp" \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/llvm17 -DLLVM_TARGETS_TO_BUILD="X86;AMDGPU;BPF" \
-DGCC_INSTALL_PREFIX=/opt/gcc13 -DLLVM_BINUTILS_INCDIR=/usr/include \
-DLLVM_BUILD_DOCS=ON -DLLVM_ENABLE_SPHINX=ON -DSPHINX_WARNINGS_AS_ERRORS=OFF \
-DOCAMLFIND=null -DLLVM_LIBDIR_SUFFIX=64 -DLLVM_ENABLE_RTTI=ON \
-DLLVM_ENABLE_FFI=ON -DLLVM_INSTALL_UTILS=ON -DLLVM_ENABLE_DUMP=ON
\ -DLIB{,CXX,CXXABI,UNWIND,}_INSTALL_LIBRARY_DIR=/opt/llvm17/lib64 \
-DLLVM_SPIRV_INCLUDE_TESTS=OFF \
-G Ninja ../llvm |
Explicación de los comandos
mkdir build64; cd build64 : Creamos
un directorio de compilación para no compilar directamente en el
directorio de las fuentes, y entramos en el mismo.
-DLLVM_ENABLE_PROJECTS="clang;lld;polly;compiler-rt;openmp":
Activa la compilación de los proyectos separados por
punto y coma, incluidos junto a LLVM en el paquete proporcionado en
este manual. Además de estos proyectos, el paquete incluye los
siguientes: bolt, clang-tools-extra, flang, libc, libcl, lldb, mlir y
pstl, que podemos añadir si así lo deseamos, a este
parámetro de configuración, aunque algunos como libclc,
no se compilan de forma efectiva y hay que compilarlos aparte.
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind"
: A partir de la versión 16 de LLVM, no es posible incluir todos
los paquetes como proyectos y debemos añadir este
parámetro en lo que respecta a los paquetes libcxx, libcxxabi y
libunwind, que serán compilados por la versión de Clang,
generada en el proceso de compilación.
-DCMAKE_BUILD_TYPE=Release : Compila la versión optimizada de LLVM.
-DCMAKE_INSTALL_PREFIX=/opt/llvm17 : Instala el compilador en /opt/llvm17.
-DGCC_INSTALL_PREFIX=/opt/gcc13 : Le indicamos la ruta de instalación de GCC, en el caso de que utilicemos otra versión diferente a la principal del sistema. Esto es necesario para que Clang encuentre las cabeceras C++ de GCC cuando tenga que compilar código escrito en C++.
-DLLVM_TARGETS_TO_BUILD="X86;AMDGDPU;BPF" : Compila sólo el soporte de la arquitectura de procesador x86, el soporte del controlador de gráficos de código abierto, AMDGPU (requerido para poder compilar Mesa con soporte de las tarjetas gráficas de AMD) y el soporte de BPF, requerido para la compilación del paquete v4l-utils, omitiendo otras como ARM, PowerPC, etc. Esto reduce el tiempo de
compilación y el tamaño del directorio de
instalación del compilador.
-DLLVM_BINUTILS_INCDIR=/usr/include : Le indicamos la ruta al archivo de cabecera plugin-api.h, proporcionado por el paquete Binutils cuando se instala con soporte de plugins. Esta versión especial es requerida para poder compilar el plugin LLVM Gold, que nos permite poder disponer de la optimización LTO, en las compilaciones que realicemos con Clang.
-DLLVM_BUILD_DOCS=ON : Activa la creación e instalación de la documentación en formato HTML y páginas de manual de LLVM y Clang.
-DLLVM_ENABLE_SPHINX=ON : Utiliza el programa Sphinx para crear la documentación en formato HTML y páginas de manual de LLVM y Clang.
-DSPHINX_WARNINGS_AS_ERRORS=OFF : Evita que los avisos sean tratados como errores, al generar la documentación en formato HTML y páginas de manual de LLVM y Clang.
-DOCAMLFIND=null : Al no tener el paquete una opción específica para desactivar la adaptación de LLVM para el lenguaje de programación OCaml, le indicamos una ruta nula al ejecutable ocamlfind,
para poder desactivar el soporte de esta dependencia. Si no tenemos
instalado OCaml en nuestro sistema, esto no hay que añadirlo.
-DLLVM_LIBDIR_SUFFIX=64 : Establece el nombre del directorio de las librerías de LLVM en lib64,
para que no sean sobrescritas en el proceso de instalación, las
librerías de la versión de 32 bits, ubicadas en /opt/llvm17/lib.
-DLLVM_ENABLE_RTTI=ON : Parámetro requerido para poder compilar Mesa con soporte de LLVM con el sistema de compilación, Meson.
-DLLVM_ENABLE_FFI=ON : Activa el soporte de Libffi, librería de características similares a GMP.
-DLLVM_CCACHE_BUILD=ON : Activa el uso de Ccache
para compilar el paquete. No es necesario si tenemos configurado Ccache
en nuestro sistema con el uso de los enlaces simbólicos
correspondientes.
-DLLVM_INSTALL_UTILS=ON : Instala las utilidades binarias FileCheck, count, lli-child-target, llvm-PerfectShutffle, not y yaml-bench
que, en el caso de FileCheck es requerido en la compilación de
algún paquete de código fuente, cuyo nombre ahora no
recuerdo. Estas utilidades se compilan por defecto, pero para
instalarlas hay que añadir esta variable al comando de
configuración del paquete.
-DLLVM_ENABLE_DUMP=ON : Requerido para poder compilar el soporte del experimental controlador gallium-rusticl de las librerías Mesa.
-DLIB{,CXX,CXXABI,UNWIND,}_INSTALL_LIBRARY_DIR=/opt/llvm17/lib64
: Evita a partir de LLVM 15, que las librerías libc++, libc++abi
y libunwind, se instalen en el directorio
/opt/llvm17/lib64/x86_64-unknown-linux-gnu, ubicándolas en el
directorio predefinido de siempre.
-G Ninja : Utiliza Ninja en lugar de GNU Make para compilar el paquete (opcional).
Parámetros de configuración opcionales
-DLLVM_CCACHE_BUILD=ON : Activa el uso de Ccache
en el proceso de compilación. Si tenemos configurado Ccache con
los correspondientes enlaces simbólicos, no es necesario
añadir esta opción. Pero sí tenemos que tener activadas las opciones de Ccache, hash_dir y run_second_cpp, que vienen activadas por defecto. En la 3ª fase de compilación sí que es necesario añadirla.
-DLLVM_BUILD_LLVM_DYLIB=ON:
Compila una librería única compartida de LLVM, a partir
de las estáticas, para poder enlazar contra la misma, paquetes
como las librerías Mesa.
Si no tenemos pensado compilar la versión compartida de LLVM,
tendremos que añadir esta opción a las opciones de
configuración del paquete.
-DLLVM_TOOL_SPIRV_LLVM_TRANSLATOR_BUILD=OFF
: Omite la compilación de SPIRV-LLVM-Translator, si no tenemos pensado compilar Libclc.
-DCMAKE_AR=$(which $AR) -DCMAKE_RANLIB=$(which $RANLIB) -DCMAKE_NM=$(which $NM) : Sincroniza las variables de entorno establecidas en el manual, relativas a los binarios ejecutables intermedios, gcc-ar, gcc-ranlib y gcc-nm, con los parámetros de configuración utilizados por CMake, relativos a los programas ar, ranlib y nm, para poder aplicar correctamente la optimización LTO.
Se utiliza el comando which para buscar los ejecutables porque desde
hace ya varias versiones, CMake no establece correctamente la ruta al
ejecutable en cuestión. Esto no es necesario hacerlo, si
compilamos el paquete con Clang.
-DLLVM_ENABLE_LTO=ON|Thin : Activa el uso de la optimización LTO,
tanto con GCC como con Clang, siempre en combinación con el
parámetro anteriormente descrito. La reducción de los
archivos binarios es irrelevante, penalizado por el aumento de
tamaño de las librerías estáticas, lo que hace que
el total de espacio requerido aumente en más de 140 MB, si
utilizamos la optimización ThinLTO con Clang. La ganancia de
velocidad (10/15 % en las comparativas de este manual) y el menor
tamaño de los binarios que genera el compilador,
independientemente de la optimización que se utilice, sí
es relevante. Si vamos a utilizar Clang, muy recomendable hacer uso de
ThinLTO en lugar de LTO, estableciendo Thin en lugar de ON, en el valor de este parámetro, para reducir el tiempo de compilación del paquete.
-DLLVM_ENABLE_LLD=ON
: Este parámetro sólo es necesario si utilizamos la
optimización ThinLTO con Clang, y no tenemos configurado un
directorio caché para LLD en nuestro sistema, cuyo uso hemos
establecido con la correspondiente variable de entorno de uso de
enlazador dinámico para LLD. El proceso de configuración
creará uno en la raíz del directorio de
compilación con el nombre lto.cache
y almacenará en el mismo los archivos objeto que se generen en
el proceso de enlazado, evitando utilizar la memoria física del
sistema, si tenemos montado el directorio /tmp con el sistema de archivos, Tmpfs.
Si se establece LLD como enlazador dinámico, antes del comando
de configuración del paquete, esta opción no será
funcional.
-DLLVM_PARALLEL_LINK_JOBS=$(nproc)
: Establece el número de procesos en paralelo de enlazado de los
binarios (por defecto es 2), tomando como referencia la
información del número de núcleos de nuestro
procesador, proporcionada por el sistema. Este parámetro
sólo es aplicable con Ninja. Si compilamos el paquete con Clang, estableciendo las correspondientes
variables de entorno de LLD de este manual, es recomendable no utilizar esta opción.
-DCMAKE_STRIP=/usr/bin/strip : Sustituye llvm-strip por strip,
en el caso de que compilemos el paquete con Clang. El segundo es
bastante mejor que el primero, a la hora de reducir el tamaño de
los binarios compilados.
Compilación
Parámetros de compilación opcionales
Instalación como root de la versión de 64 bits estática
$ su
# ninja install/strip
# mv /opt/llvm17/bin/llvm-config{,-64} |
Explicación de los comandos
mv /opt/llvm17/bin/llvm-config{,-64}
: Renombramos el ejecutable encargado de mostrar la
información sobre la ubicación de las librerías de
LLVM en los procesos de compilación en los que sea necesario su
uso, siguiendo el método utilizado por el CLFS.
Crear el binario ejecutable selector de arquitectura de procesador siguiendo el método del CLFS
Nos descargamos este archivo
y lo compilamos como root con el siguiente comando, para posteriormente
crear el enlace simbólico correspondiente para poder alternar de
una arquitectura a otra, en el uso de dependencias, en función
del proceso de compilación en curso.
# gcc multiarch_wrapper.c -o /opt/llvm17/bin/multiarch_wrapper
# ln -s multiarch_wrapper /opt/llvm17/bin/llvm-config
|
Cuando compilemos código de 32 bits, que necesite de las
dependencias de las librerías de 32 bits de LLVM, ejecutamos la
siguiente variable de entorno, antes de configurar los paquetes de
código fuente correspondientes.
Configuración de Libclc
Este apartado sólo es para los usuarios
de tarjetas
gráficas de AMD, que quieran hacer uso de OpenCL con las
librerías Mesa. Para ello necesitaremos instalar Libclc y
SPIRV-LLVM-Translator (requerido sólo el binario ejecutable para compilar Libclc) y
también, requerido para compilar el soporte de SPIRV en el
controlador Clover de Gallium de las librerías Mesa. La
versión de SPIRV-LLVM-Translator tiene que ser siempre la misma
que la serie de LLVM, incluyendo claro está las versiones de
corrección de errores de LLVM. En el paquete incluido en este
manual de LLVM ya existe una versión que he añadido para
ahorrarnos más enlaces de descarga.
Utilizaremos los binarios ejecutables creados en la anterior
compilación, estableciendo las correspondientes variables de
entorno.
$ export PATH=$PWD/build64/bin:$PATH
$ export LLVM_DIR=$PWD/build64/lib64/cmake/llvm
$ cd libclc
$ mkdir build; cd build
$ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/llvm17 -G Ninja .. |
Compilación
Instalación como root
$ su -c "ninja install"
$ unset LLVM_DIR
$ cd ../..
|
3) Configuración
de la versión de 64 bits compartida (sólo librerías de LLVM, Clang, Polly y SPIRV-LLVM-Translator)
Esta opción soluciona problemas de enlazado de paquetes como
SPIRV-LLVM-Translator, que mezclan librerías de LLVM compartidas
con estáticas en el proceso de enlazado con duplicación
de símbolos, produciendo errores de
ejecución y compilación en paquetes como Mesa, cuando
compilamos el soporte de OpenCL en las mismas. Lo bueno de esta
opción es que reduce la instalación anterior de LLVM en
1,3 GB. Se utilizan los binarios ejecutables creados en la anterior
compilación y establecemos el PATH correspondiente de su
ubicación. Si estamos utilizando la misma ventana de terminal de
la compilación de Libclc, no es necesario establecer la variable
de entorno PATH.
$ export PATH=$PWD/build64/bin:$PATH
$ mkdir build64s; cd build64s
$ cmake -DLLVM_ENABLE_PROYECTS="clang;polly" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/llvm17 -DBUILD_SHARED_LIBS=ON -DLLVM_TARGETS_TO_BUILD="X86;AMDGPU;BPF" \
-DGCC_INSTALL_PREFIX=/opt/gcc13 -DLLVM_BINUTILS_INCDIR=/usr/include -DOCAMLFIND=null \
-DLLVM_LIBDIR_SUFFIX=64 -DLLVM_ENABLE_RTTI=ON -DLLVM_ENABLE_FFI=ON -DCLANG_BUILD_TOOLS=OFF \
-DLLVM_ENABLE_LTO=Thin -DLLVM_CCACHE_BUILD=ON -DLLVM_ENABLE_DUMP=ON \
-DLLVM_SPIRV_INCLUDE_TESTS=OFF -G Ninja ../llvm |
Compilación
Instalación
como root de la versión de 64 bits compartida (sólo
librerías de LLVM, Clang, Polly y SPIRV-LLVM-Translator)
$ su
# ninja install/strip
# mv /opt/llvm17/bin/llvm-config{,-64}
# ln -s multiarch_wrapper /opt/llvm17/bin/llvm-config |
Borrar las librerías estáticas de la 2ª fase de compilación
Esto es opcional, pero su instalación ocupa casi 500 MB. Al
instalar la versión compartida de LLVM éstas quedan
anuladas en cualquier proceso de compilación que realicemos, a
no ser que forcemos una compilación estática, algo poco
habitual en un proceso de compilación en nuestro sistema.
# find /opt/llvm17/lib64 -maxdepth 1 -name '*.a' -type f -delete |
Borrar los archivos de instalación que hacen referencia a la
versión 17.0.5, sobrescrita por esta nueva versión
Hacer sólo esto si estamos actualizando desde la versión
anterior instalada siguiendo las instrucciones de este manual. Con el
siguiente comando, borramos los archivos de instalación
de la versión anterior.
# for i in 17.0.5 ; do \
rm -f /opt/llvm17/lib{,64}/libclang.so.$i ; \
done |
Estadísticas de Compilación e Instalación de LLVM
Estadísticas de Compilación e Instalación de LLVM |
CPU |
AMD Ryzen 5 5500 |
MHz |
3593.250 (BoostMax=4457.000) |
RAM |
32 GB |
Sistema de archivos |
XFS |
Versión del Kernel |
6.6.2-ml SMP PREEMPT_DYNAMIC x86_64 |
Modo de frecuencia de la CPU |
powersave (balance performance) |
Planificador de CPU |
BORE |
Versión de Glibc |
2.38 |
Enlazador dinámico |
LLD 17.0.5 |
Compilador |
Clang 17.0.5 + Ccache 4.8.3 |
Parámetros de optimización del modo de 32 bits |
-03 -march=i686
-mtune=athlon-xp -mllvm -polly -mllvm -polly-vectorizer=stripmine
-flto=thin -Wl,--thinlto-jobs=6 -Wl,--lto-aa-pipeline=globals-aa
-Wl,--lto-newpm-passes=memcpyopt |
Parámetros de optimización del modo de 64 bits |
-03 -march=znver3
-mtune=znver3 -mllvm -polly -mllvm -polly-vectorizer=stripmine
-flto=thin -Wl,--thinlto-jobs=6 -Wl,--lto-aa-pipeline=globals-aa
-Wl,--lto-newpm-passes=memcpyopt |
Parámetros de compilación |
-v -j12 |
Ocupación de espacio en disco del proceso de compilación |
9,5 GB |
Tiempo de compilación de la versión de 32 bits |
25' 23" |
Tiempo de compilación de la versión de 64 bits estática (incluye libclc) |
55' 23" |
Tiempo de compilación de la versión de 64 bits compartida |
25' 41" |
Tiempo total consumido |
1h 46' 27" |
Archivos instalados |
8.134 |

|
Enlaces simbólicos creados |
383 |

|
Ocupación de espacio en disco |
1,5 GB |
Desinstalación como root
1) MODO TRADICIONAL
Este programa no tiene soporte para desinstalación con el comando 'ninja uninstall'
2) MODO MANUALINUX
El principal inconveniente del comando anterior es que tenemos que
tener el directorio de compilación en nuestro sistema para poder
desinstalar el programa. En algunos casos esto supone muchos megas de
espacio en disco. Con el paquete de scripts que pongo a
continuación logramos evitar el único inconveniente que
tiene la compilación de programas, y es el tema de la
desinstalación de los mismos sin la necesidad de tener
obligatoriamente una copia de las fuentes compiladas.
llvm-17.0.6-scripts.tar.gz
$ su
# tar zxvf llvm-17.0.6-scripts.tar.gz
# cd llvm-17.0.6-scripts
# ./Desinstalar_llvm-17.0.6 |
Copia de Seguridad como root
Con este otro script creamos una copia de seguridad de los binarios
compilados, recreando la estructura de directorios de los mismos en un
directorio de copias de seguridad (copibin) que se crea en el directorio /var. Cuando se haya creado el paquete comprimido de los binarios podemos copiarlo como usuario a nuestro home
y borrar el que ha creado el script de respaldo, teniendo en cuenta que
si queremos volver a restaurar la copia, tendremos que volver a
copiarlo al lugar donde se ha creado.
$ su
# tar zxvf llvm-17.0.6-scripts.tar.gz
# cd llvm-17.0.6-scripts
# ./Respaldar_llvm-17.0.6 |
Restaurar la Copia de Seguridad como root
Y con este otro script (que se copia de forma automática cuando
creamos la copia de respaldo del programa) restauramos la copia de
seguridad como root cuando resulte necesario.
$ su
# cd /var/copibin/restaurar_copias
# ./Restaurar_llvm-17.0.6
|
Configurar el sistema para el uso de Clang
1) /etc/ld.so.conf
Añadimos la ruta a las librerías compartidas en el archivo /etc/ld.so.conf.
include ld.so.conf.d/*.conf
/usr/X11R6/lib
/usr/lib
/usr/lib/qt3/lib
/usr/local/lib
/opt/e17/lib
/opt/llvm17/lib64
/opt/llvm17/lib
|
Cuando lo hayamos editado y guardado ejecutamos la actualización de la caché de las librerías compartidas.
2) Añadir la ruta a los binarios y las páginas de manual a nuestro PATH
2a) Variable de entorno PATH de usuario
Editamos el archivo de nuestro home, ~/.bashrc (si no existe lo creamos) y añadimos lo siguiente al final del mismo:
export PATH=/opt/llvm17/bin:$PATH
export MANPATH=/opt/llvm17/share/man:$MANPATH
|
2b) Variable de entorno PATH del sistema
Si queremos establecer una variable de entorno global del sistema, abrimos un editor de texto y añadimos lo siguiente:
#!/bin/sh
export PATH=/opt/llvm17/bin:$PATH
export MANPATH=/opt/llvm17/share/man:$MANPATH
|
Lo guardamos con el nombre clang.sh, y lo instalamos en /etc/profile.d.
$ su -c "install -m755 clang.sh /etc/profile.d" |
Tenemos que cerrar el emulador de terminal y volverlo a abrir para que
la variable de entorno aplicada sea efectiva. Es conveniente guardar
una copia de este script para posteriores instalaciones de nuestro
sistema. La ventaja de utilizar el directorio /etc/profile.d es que es común a todas las distribuciones y nos evita tener que editar otros archivos del sistema como por ejemplo, /etc/profile.
Para comprobar que el binario clang está incluido en el path, abrimos una ventana de terminal y ejecutamos el siguiente comando:
[jose@localhost ~]$ clang --version
clang version 17.0.6
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/llvm17/bin
|
2c) Lectura de las páginas de manual
2d) Lectura de la documentación en formato HTML
/opt/llvm17/share/doc/LLVM/llvm/html/index.html | /opt/llvm17/share/doc/LLVM/clang/html/index.html
2) Establecer la variable PKG_CONFIG_PATH requerida por el programa pkg-config
Establecemos la correspondiente variable de entorno para que el programa pkg-config encuentre
los archivos de referencia (*.pc) de las dependencias
requeridas en los procesos de compilación pertinentes.
Sólo es necesario si hemos instalado las
librerías LLVMSPIRVLib y Libclc, siguiendo este manual.
En el archivo que hemos creado anteriormente (clang.sh) añadimos lo que está en rojo:
#!/bin/sh
export PATH=/opt/llvm17/bin:$PATH
export MANPATH=/opt/llvm17/share/man:$MANPATH
export
PKG_CONFIG_PATH=/opt/llvm17/lib64/pkgconfig:/opt/llvm17/share/pkgconfig:$PKG_CONFIG_PATH
|
En la versión de 32 bits de LLVMSPIRVLib y, además,
Libclc, que no es una librería propiamente dicho, allí
donde se
requiera su dependencia lo haremos de forma manual, añadiendo la
ruta correspondiente a la variable de entorno PKG_CONFIG_PATH a
establecer, un ejemplo:
$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:\
/opt/llvm17/lib/pkgconfig:/opt/llvm17/share/pkgconfig:/usr/share/pkgconfig:$PKG_CONFIG_PATH
|
Optimizaciones de CPU para Clang
Los procesadores soportados por Clang, son practicamente los mismos que los de GCC,
con las excepciones en las que se permite más de una
definición para hacer referencia a un determinado procesador.
Por ejemplo, barcelona no está soportado por Clang, hasta la versión 3.6, con lo que tendremos que utilizar el otro término alternativo: amdfam10. El parámetro '-mtune' ha sido introducido a partir de la versión 3.4 de Clang. Si utilizamos versiones anteriores, tendremos que utilizar '-mcpu'.
La tabla que pongo a
continuación no difiere mucho de la utilizada en los manuales de
instalación ubicados en la web, las filas con el color amarillo
indican las definiciones de procesador soportadas por Clang, que no aparecen en las opciones de optimización de GCC.
$ export {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3'
|
Donde pone znver3 se indica el procesador respectivo de cada sistema seleccionándolo de la siguiente tabla: |
Nota informativa sobre las optimizaciones para GCC
|
* La opción '-march=' establece el procesador mínimo con el que funcionará el programa compilado, la opción '-mtune=' el procesador específico para el que será optimizado.
* Los valores separados por comas, son equivalentes, es decir, que lo mismo da poner '-march=k8' que '-march=athlon64'.
* En versiones de GCC 3.2 e inferiores se utiliza la opción '-mcpu=' en lugar de '-mtune='.
|
Nota informativa sobre las optimizaciones para Clang
|
* La opción '-mtune=' está soportada a partir de la versión 3.4 de Clang.
* Los valores de color azul no son compatibles con Clang.
* Las filas con el fondo de color amarillo son valores exclusivos de Clang y, por lo tanto, no son aplicables con GCC.
|
Valores |
CPU |
Genéricos |
generic |
Produce un código binario
optimizado para la mayor parte de procesadores existentes. Utilizar
este valor si no sabemos el nombre del procesador que tenemos en
nuestro equipo. Este valor sólo es aplicable en la opción
'-mtune=', si utilizamos GCC. Esta opción está disponible a partir de GCC 4.2. |
native |
Produce un código binario
optimizado para el procesador que tengamos en nuestro sistema, siendo
éste detectado utilizando la instrucción cpuid.
Procesadores antiguos pueden no ser detectados utilizando este valor.
Esta opción está disponible a partir de GCC 4.2. |
x86-64 |
Procesador genérico con extensiones 64-bit. Esta opción está disponible a partir de GCC 8 y Clang 1.9. |
x86-64-v2 |
Procesador genérico con con
soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT,
SSE3, SSE4.1, SSE4.2, SSSE3) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
x86-64-v3 |
Procesador genérico con con
soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT,
SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C, FMA, LZCNT, MOVBE, XSAVE,
XSAVEC, FMA4) y extensiones 64-bit. Esta opción está
disponible a partir de GCC 11 y Clang 12. |
x86-64-v4 |
Procesador genérico con con
soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT,
SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C, FMA, LZCNT, MOVBE, XSAVE,
XSAVEC, AVX512*, FMA4) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
Intel |
alderlake |
Intel Alderlake con soporte de
instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI,
AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE,
PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE,
AMX-INT8, AVX-VNNI) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
atom |
Intel Atom con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y extensiones
64-bit. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición bonnell. |
bonnell |
Intel Bonnell con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3 y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9. |
broadwell |
Intel Broadwell con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW y extensiones 64-bit. Esta opción
está disponible a partir de GCC 4.9 y Clang 3.6. |
cannonlake |
Intel Cannonlake Server con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA,
UMIP y extensiones 64-bit. Esta opción está
disponible a partir de GCC 8 y Clang 3.9. |
cascadelake |
Intel Cascadelake con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI y extensiones
64-bit. Esta opción está disponible a partir de GCC 9 y Clang 8. |
cooperlake |
Intel Cooper
Lake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND,
FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC,
XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD,
AVX512VNNI, AVX512BF16 y extensiones 64-bit. Esta opción
está disponible a partir de GCC 10 y Clang 9. |
core2 |
Intel Core2 con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y extensiones 64-bit. Esta
opción está disponible a partir de GCC 4.3. |
core-avx2 |
Intel Core (Haswell). Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición haswell. |
core-avx-i |
Intel Core (ivyBridge)
con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, AVX, AES, PCLMUL, FSGSBASE, RDRND, F16C y extensiones
64-bit. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición ivybridge. |
corei7 |
Intel Core i7 con soporte
de instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 y SSE4.2 y
extensiones 64-bit. Soporta también los procesadores Intel Core
i3 e i5. Esta opción está disponible desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición nehalem. |
corei7-avx |
Intel Core i7 con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AES y
PCLMUL y extensiones 64-bit. Soporta también los procesadores
Intel Core i3 e i5. Esta opción está disponible
desde GCC 4.6, hasta GCC 4.8. A partir de GCC 4.9 se utiliza la definición sandybridge. |
emeraldrapids |
Intel Emerald Rapids. Esta opción está disponible a partir de GCC 13 y Clang 16. |
goldmont |
Intel Goldmont con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE y extensiones
64-bit. Esta opción está disponible a partir de GCC 9 y Clang 5. |
goldmont-plus |
Intel Goldmont Plus con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE, RDPID,
SGX, UMIP y extensiones 64-bit. Esta opción está
disponible a partir de GCC 9 y Clang 7. |
grandridge |
Intel Grand Ridge con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES, XSAVEOPT,
FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI, MOVDIR64B,
CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT,
PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, RAOINT y
extensiones 64-bit. Esta opción está disponible a partir
de GCC 13 y Clang 16. |
graniterapids |
Intel Grand Ridge con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, CX16, SAHF, FXSR, AVX, XSAVE, PCLMUL, FSGSBASE, RDRND, F16C,
AVX2, BMI, BMI2, LZCNT, FMA, MOVBE, HLE, RDSEED, ADCX, PREFETCHW, AES,
CLFLUSHOPT, XSAVEC, XSAVES, SGX, AVX512F, AVX512VL, AVX512BW, AVX512DQ,
AVX512CD, PKU, AVX512VBMI, AVX512IFMA, SHA, AVX512VNNI, GFNI, VAES,
AVX512VBMI2, VPCLMULQDQ, AVX512BITALG, RDPID, AVX512VPOPCNTDQ, PCONFIG,
WBNOINVD, CLWB, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD,
CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16,
AMX-TILE, AMX-INT8, AVX-VNNI, AVX512-FP16, AVX512BF16, AMX-FP16,
PREFETCHI y extensiones 64-bit. Esta opción está
disponible a partir de GCC 13 y Clang 16. |
graniterapids-d |
Intel Xeon Granite Rapids-D. Esta opción está
disponible a partir de Clang 17. |
haswell |
Intel Haswell con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 4.9. |
i386 |
Intel i386.
|
i486 |
Intel i486. |
i586, pentium |
Intel Pentium sin soporte de instrucciones MMX. |
i686 |
Produce un código binario
optimizado para la mayor parte de procesadores compatibles con la serie
80686 de Intel. Todos los actuales lo son. |
icelake-client |
Intel Icelake Client con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA,
CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG,
AVX512VNNI, VPCLMULQDQ, VAES y extensiones 64-bit. Esta
opción está disponible a partir de GCC 8 y Clang 7. |
icelake-server |
Intel Icelake Server con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2,
F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F,
AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA,
CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG,
AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG, WBNOINVD y extensiones
64-bit. Esta opción está disponible a partir de GCC 8 y Clang 7. |
intel |
Intel Haswell y Silvermont. Este
valor sólo es aplicable en la opción '-mtune='. Esta
opción está disponible a partir de GCC 4.9. |
ivybridge |
Intel Ivy Bridge con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX,
AES, PCLMUL, FSGSBASE, RDRND, F16C y extensiones 64-bit. Esta
opción está disponible a partir de GCC 4.9. |
knl |
Intel Knights Landing con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW, AVX512F, AVX512PF, AVX512ER y extensiones
64-bit. Esta opción está disponible a partir de GCC 5 y Clang 3.4. |
knm |
Intel Knights Mill con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW, AVX512F, AVX512PF, AVX512ER, AVX512CD,
AVX5124VNNIW, AVX5124FMAPS, AVX512VPOPCNTDQ y extensiones 64-bit. Esta
opción está disponible a partir de GCC 8 y Clang 6. |
lakemont |
Intel Quark Lakemont MCU, basado en el procesador Intel Pentium. Esta opción está disponible a partir de GCC 6 y Clang 3.9. |
meteorlake |
Intel Meteor Lake. Esta opción está disponible a partir de GCC 13 y Clang 16. |
nehalem |
Intel Nehalem con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT y
extensiones 64-bit. Esta opción está disponible a
partir de GCC 4.9. |
nocona |
Versión mejorada de Intel Pentium4 con soporte de instrucciones MMX, SSE, SSE2, SSE3 y extensiones 64-bit. |
penryn |
Intel Penryn con soporte de instrucciones MMX, SSE, SSE2, SSE3, SSSE3 y SSE4.1. |
pentiumpro |
Intel PentiumPro. |
pentium2 |
Intel Pentium2 basado en PentiumPro con soporte de instrucciones MMX. |
pentium3, pentium3m |
Intel Pentium3 basado en PentiumPro con soporte de instrucciones MMX y SSE. |
pentium4, pentium4m |
Intel Pentium4 con soporte de instrucciones MMX, SSE y SSE2. |
pentium-m |
Versión de bajo consumo de
Intel Pentium3 con soporte de instrucciones MMX, SSE y SSE2. Utilizado
por los portátiles Centrino. |
pentium-mmx |
Intel PentiumMMX basado en Pentium con soporte de instrucciones MMX. |
prescott |
Versión mejorada de Intel Pentium4 con soporte de instrucciones MMX, SSE, SSE2 y SSE3. |
raptorlake |
Intel Raptor Lake. Esta opción está disponible a partir de GCC 13 y Clang 16. |
rocketlake |
Intel Rocket Lake con soporte de
instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 11 y Clang 13. |
sandybridge |
Intel Sandy Bridge con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX,
AES, PCLMUL y extensiones 64-bit. Esta opción está
disponible a partir de GCC 4.9 y Clang 3.6. |
sapphirerapids |
Intel Sapphire Rapids con soporte
de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI,
AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE,
PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE,
AMX-INT8 and AVX-VNNI) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
silvermont |
Intel Silvermont con soporte de
instrucciones MOVBE, MMX, SSE, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3,
SSE4.1, SSE4.2, POPCNT, AES, PCLMU, RDRND y extensiones
64-bit. Esta opción está disponible a partir de GCC 4.9 y Clang 3.6. |
sierraforest |
Intel Sierra Forest con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, XSAVES, XSAVEOPT,
FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI, MOVDIR64B,
CLDEMOTE, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT,
PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, KL, WIDEKL,
AVX-VNNI, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD y extensiones
64-bit. Esta opción está disponible a partir de GCC 13 y Clang 16. |
skylake |
Intel Skylake con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES y extensiones
64-bit. Esta opción está disponible a partir de GCC 6 y Clang 3.6. |
skylake-avx512 |
Intel Skylake Server con soporte
de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C,
RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL,
AVX512BW, AVX512DQ, AVX512CD y extensiones 64-bit. Esta opción
está disponible a partir de GCC 6 y Clang 3.9. |
tigerlake |
Intel Tiger Lake
con soporte de instrucciones OVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1,
SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI,
BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES,
AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI,
AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ,
AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG, WBNOINVD, MOVDIRI,
MOVDIR64B, AVX512VP2INTERSECT y extensiones 64-bit. Esta opción
está disponible a partir de GCC 10 y Clang 10. |
tremont |
Intel Tremont con soporte de
instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2,
POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE, RDPID,
SGX, UMIP, GFNI-SSE, CLWB, ENCLV y extensiones 64-bit. Esta
opción está disponible a partir de GCC 9 y Clang 7. |
westmere |
Intel Westmere con soporte de
instrucciones MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES,
PCLMUL y extensiones 64-bit. Esta opción está
disponible a partir de GCC 4.9. |
yonah |
Procesadores basados en la microarquitectura de Pentium M, con soporte de instrucciones MMX, SSE, SSE2 y SSE3. |
AMD |
amdfam10, barcelona |
Procesadores basados en AMD Family
10h core con soporte de instrucciones x86-64 (MMX, SSE, SSE2, SSE3,
SSE4A, 3DNow!, enhanced 3DNow!, ABM y extensiones 64-bit). Esta
opción está disponible a partir de GCC 4.3. La definición barcelona está disponible a partir de Clang 3.6. |
athlon, athlon-tbird |
AMD Athlon con soporte de instrucciones MMX, 3DNow!, enhanced 3DNow! y SSE prefetch. |
athlon4, athlon-xp, athlon-mp |
Versiones mejoradas de AMD Athlon con soporte de instrucciones MMX, 3DNow!, enhanced 3DNow! y full SSE. |
bdver1 |
Procesadores basados en AMD Family
15h core con soporte de instrucciones x86-64 (FMA4, AVX, XOP, LWP, AES,
PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM
y extensiones 64-bit). Esta opción está disponible a
partir de GCC 4.7. |
bdver2 |
Procesadores basados en AMD Family
15h core con soporte de instrucciones x86-64 (BMI, TBM, F16C, FMA, LWP,
AVX, XOP, LWP, AES, PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3,
SSE4.1, SSE4.2, ABM y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.7. |
bdver3 |
Procesadores basados en AMD Family
15h core con soporte de instrucciones x86-64 (FMA4, AVX, XOP, LWP, AES,
PCL_MUL, CX16, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM
y extensiones 64-bit). Esta opción está disponible a
partir de GCC 4.8 y Clang 3.4. |
bdver4 |
Procesadores basados en AMD Family
15h core con soporte de instrucciones x86-64 (BMI, BMI2, TBM, F16C,
FMA, FMA4, FSGSBASE, AVX, AVX2, XOP, LWP, AES, PCL_MUL, CX16, MOVBE,
MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM y extensiones
64-bit). Esta opción está disponible a partir de GCC 4.9 y Clang 3.5. |
btver1 |
Procesadores basados en AMD Family
14h core con soporte de instrucciones x86-64 (MMX, SSE, SSE2, SSE3,
SSE4A, CX16, ABM y extensiones 64-bit). Esta opción
está disponible a partir de GCC 4.6. |
btver2 |
Procesadores basados en AMD Family
16h core con soporte de instrucciones x86-64 (MOVBE, F16C, BMI, AVX,
PCL_MUL, AES, SSE4.2, SSE4.1, CX16, ABM, SSE4A, SSSE3, SSE3, SSE2, SSE,
MMX y extensiones 64-bit). Esta opción está
disponible a partir de GCC 4.8. |
geode |
AMD integrado con soporte de instrucciones MMX y 3DNow!. Esta opción está disponible a partir de GCC 4.3. |
k6 |
AMD K6 con soporte de instrucciones MMX. |
k6-2, k6-3 |
Versiones mejoradas de AMD K6 con soporte de instrucciones MMX y 3DNow!. |
k8, opteron, athlon64, athlon-fx |
Procesadores basados en AMD K8 core
con soporte de instrucciones x86-64 (MMX, SSE, SSE2, 3DNow!, enhanced
3DNow! y extensiones 64-bit). |
k8-sse3, opteron-sse3, athlon64-sse3 |
Versiones mejoradas de AMD K8 core
con soporte de instrucciones SSE3. Esta opción está
disponible a partir de GCC 4.3. |
znver1 |
Procesadores basados en AMD Family
17h core con soporte de instrucciones x86-64 (BMI, BMI2, F16C, FMA,
FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES, PCL_MUL,
CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM,
XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y extensiones 64-bit). Esta
opción está disponible a partir de GCC 6 y Clang 4. |
znver2 |
Procesadores basados en AMD Family
17h core con soporte de instrucciones x86-64 (BMI, BMI2, ,CLWB, F16C,
FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES,
PCL_MUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1,
SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y extensiones
64-bit). Esta opción está disponible a partir de GCC 9 y Clang 9. |
znver3 |
Procesadores basados en AMD Family
19h core con soporte de instrucciones x86-64 (BMI, BMI2, CLWB, F16C,
FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES,
PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1,
SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID, WBNOINVD, PKU,
VPCLMULQDQ, VAES) y extensiones 64-bit. Esta opción
está disponible a partir de GCC 11 y Clang 12. |
znver4 |
Procesadores basados en AMD Family
19h core con soporte de instrucciones x86-64 (BMI, BMI2, CLWB, F16C,
FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES,
PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1,
SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID, WBNOINVD, PKU,
VPCLMULQDQ, VAES, AVX512F, AVX512DQ, AVX512IFMA, AVX512CD, AVX512BW,
AVX512VL, AVX512BF16, AVX512VBMI, AVX512VBMI2, AVX512VNNI,
AVX512BITALG, AVX512VPOPCNTDQ, GFNI) y extensiones 64-bit. Esta
opción está disponible a partir de GCC 12.3 y Clang 16. |
Niveles de optimización soportados por Clang
Niveles de optimización soportados por Clang
|
-O0
|
Sin optimizaciones. Es el nivel más rápido para compilar programas y genera el código más depurable.
|
-O1
|
Un nivel intermedio entre -O0 y -O2.
|
-O2 |
Un nivel moderado de optimización.
|
-O3
|
Lo mismo que -O2,
excepto que permite optimizaciones que alargan el proceso de
compilación y pueden llegar a generar un binario de
tamaño más grande, con la idea de hacer que se ejecute
más rápido.
|
-Ofast
|
Activa todas las optimizaciones de -O3,
junto con otras optimizaciones agresivas que pueden violar el estricto
cumplimiento de los estándares del lenguaje de
programación.
|
-Os
|
Lo mismo que -O2, con optimizaciones adicionales para reducir el tamaño del binario resultante.
|
-Oz |
Lo mismo que -Os, pero con una reducción de tamaño del binario resultante, más agresiva.
|
-O
|
Equivalente a -O2.
|
-O4 y superiores
|
Actualmente equivale a -O3.
|
-Og |
Equivalente a -O1. |
Optimizaciones adicionales para Clang
Optimizaciones adicionales para Clang
|
Polly |
-mllvm -polly |
Activa el uso de Polly, un optimizador de características similares a la optimización Graphite de GCC.
Este optimizador solo funciona en el nivel '-O3' de
optimización. Puede provocar errores de compilación
y de ejecución en determinados paquetes.
La definición de la optimización Graphite también es válida para Polly y consiste en utilizar la representación de la figura geométrica del poliedro
para ejecutar en paralelo los bucles de programación que
contenga el código fuente de un programa, en el binario
resultante del proceso de compilación, acelerando de forma
considerable el tiempo de ejecución del mismo. |
-mllvm -polly-vectorizer=stripmine |
Activa la generación automática de código vectorizado, a través de Polly. Este parámetro debe ir precedido del anterior. Desde Clang 3.5 es el parámetro predefinido de Polly utilizado en los manuales de la web. A partir de la versión 3.7, se ha sustituido el valor polly por stripmine. El primer valor se ha eliminado a partir de Clang 17.
|
-mllvm -polly-parallel |
Activa la generación automática de código OpenMP, a través de Polly.
Este parámetro debe ir precedido del inicial de esta
sección. Este parámetro lo pongo como experimental, y
sólo lo podremos aplicar en aquellos paquetes que contengan
código OpenMP, en combinación con el utilizado por el compilador para dicho proceso. |
-mllvm-polly-omp-backend=LLVM |
Activa que Polly utilice libomp en lugar de libgomp (GNU) que es la predefinida, para generar el código OpenMP. |
-mllvm -polly-position=before-vectorizer |
Activa que Polly
se ejecute antes que LLVM en el proceso de optimización y no
después, que es el modo de trabajar predefinido. Este
parámetro debe ir precedido del inicial de esta sección.
En determinados procesos de compilación puede mejorar la
optimización del binario resultante. En otros la puede empeorar.
Más información en este enlace.
|
-mllvm -polly-2nd-level-tiling |
Activa un segundo nivel de
optimización de mosaico de bucle. Por defecto, Polly tiene
activada la optimización de mosaico (tiling). Con esta
opción hacemos que le dé otra pasada más profunda
de este tipo de optimización específico, al código
a compilar. |
-mllvm -polly-pattern-matching-based-opts |
Activa optimizaciones basadas en patrones idénticos. |
-mllvm -polly-loop-fusion-greedy |
Intenta fusionar de forma agresiva
todos los bucles de programación, independientemente del
rendimiento que pueda producir. Esta opción está a partir
de la versión 14 de Polly. |
LTO |
-flto |
Activa la optimización LTO, equivalente a la optimización LTO de GCC.
Puede provocar errores de compilación y de ejecución en
determinados paquetes. Tenemos que tener instalado y configurado el
paquete Binutils, con el enlazador dinámico ld.gold como el predefinido del sistema, para que este parámetro sea funcional. La otra alternativa es utilizar LLD como enlazador dinámico.
Además de haber compilado el plugin LLVM Gold
como se explica en este manual. La carga de este plugin se realiza de
forma automática, sin tener que añadir ningún
parámetro adicional.
En procesos de compilación que se generen librerías estáticas, o que intervenga el programa nm de Binutils, tendremos que establecer la siguiente variable de entorno, antes de ejecutar el script de configuración del paquete.
$ export AR=llvm-ar RANLIB=llvm-ranlib NM=llvm-nm |
En el manual de GCC
explico de forma más extendida el porqué del uso de esta
variable de entorno, en la sección de preguntas y respuestas
relacionada con la optimización LTO.
|
ThinLTO |
-flto=thin |
ThinLTO
es una variante más agresiva de LTO, introducida a partir de la
versión 3.9 de LLVM. Lo que se busca con esta
optimización es reducir a la mínima expresión el
tiempo necesario para generar el binario ejecutable correspondiente a
partir de los archivos objeto que intervengan en el proceso de enlace,
aprovechando la capacidad multinúcleo de los procesadores
actuales, que es el principal inconveniente que se nos presenta cuando
hacemos uso de la tradicional optimización LTO. Podemos
encontrar más información y la correspondiente
comparativa en esta entrada del blog de la web de LLVM.
A diferencia de LTO que utiliza sólo un archivo objeto para
volcar el proceso de enlazado, ThinLTO divide el mismo en
múltiples archivos objeto, lo que puede llegar a rebasar el
límite de procesos por usuario establecidos en nuestro sistema,
impidiendo por ejemplo, si tenemos un limite de 1024, que en paquetes
como Inkscape o GTK3, no podamos utilizar esta optimización.
Para solucionar este inconveniente, primero comprobaremos el
límite de procesos por usuario que tenemos en nuestro sistema
con el siguiente comando:
[jose@localhost ~]$ ulimit -n
1024 |
En mi caso personal son 1024, que elevo a 4096, con el mismo comando al que le añado el número dado.
Como este valor es volátil y desaparece cuando reiniciamos el
sistema, creamos el script correspondiente para que dicho valor quede
establecido por defecto al inicio del sistema. Abrimos un editor de
texto y añadimos lo siguiente:
Lo guardamos con el nombre ulimit.sh y lo instalamos en /etc/profile.d.
$ su -c "install -m755 ulimit.sh /etc/profile.d" |
En el siguiente reinicio del sistema, comprobamos que el valor establecido por el script es el que está en uso.
[jose@localhost ~]$ ulimit -n
4096 |
|
Unified LTO |
-funified-lto
-Wl,--lto=full o thin |
A partir de Clang 17, se
introduce esta opción de compilación, que permite
combinar una optimación LTO o ThinLTO en el proceso previo al
enlazado, con una optimización LTO o ThinLTO, en el posterior
enlazado con LLD. Podemos encontrar más información en
este enlace.
La aplicación real de la misma sirve para reducir el tiempo de
compilación de una optimización LTO, al introducir la
posibilidad de aplicar una optimización ThinLTO en el proceso de
enlazado con LLD, al unificar el código LTO en una sóla
estructura compatible con las dos optimizaciones. Si lo hacemos a la
inversa, compilar con ThinLTO y enlazar con LTO, los tiempos de
compilación se disparan de forma exponencial.
Un ejemplo con LTO+ThinLTO de variable de entorno a establecer sería este:
$ export {C,CXX}FLAGS+=" -flto -funified-lto"
$ export LDFLAGS+=" -Wl,--lto=thin"
|
Y viceversa,
$ export {C,CXX}FLAGS+=" -flto=thin -funified-lto"
$ export LDFLAGS+=" -Wl,--lto=full"
|
Las optimizaciones adicionales LTO y ThinLTO para LLD, siguen siendo
igual de aplicables, en función del tipo de optimización
que elijamos a utilizar por el enlazador.
|
OpenMP |
-fopenmp=libomp
|
OpenMP
es una API de programación creada única y exclusivamente
para aprovechar la potencia de los procesadores multinúcleo, si
el nuestro no lo es, no es necesario seguir leyendo esto. Esta
optimización sólo es operativa en aquellos paquetes de
código fuente que están previamente preparados para
utilizarla: ImageMagick, Blender, Inkscape, etc.
La versión actual de Clang es compatible con la
versión 5.0 de OpenMP e inferiores. El parámetro a
añadir varía del utilizado por GCC, y permite elegir
qué librería utilizar para el enlazado del binario
ejecutable. Si no especificamos ninguna y dejamos que el script de
configuración del paquete detecte el parámetro -fopenmp,
el mismo se enlazará contra la librería libomp de LLVM.
En versiones antiguas de Clang, se enlaza por defecto contra la
librería libgomp de GCC.
Desde la versión 3.9 de Clang, también se puede
seleccionar la versión de OpenMP a utilizar por el compilador,
en el caso de que el script de configuración del paquete, no
detecte de forma correcta la versión más reciente. En
este caso el parámetro a añadir al inicial, sería
uno de los siguientes:
-fopenmp-version=31 >> OpenMP 3.1
-fopenmp-version=40 >> OpenMP 4.0
-fopenmp-version=45 >> OpenMP 4.5 (versión predefinida de Clang 10 si sólo se utiliza el parámetro -fopenmp)
-fopenmp-version=50
>> OpenMP 5.0 (a partir de Clang 10. Versión
predefinida de Clang 11 si sólo se utiliza el
parámetro -fopenmp)
-fopenmp-version=51 >> OpenMP 5.1 (a partir de Clang 11. Soporte en fase previa de implementación)
Que quedaría así en una variable de entorno, un ejemplo con OpenMP 4.5:
$ export {C,CXX}FLAGS+=" -fopenmp=libomp -fopenmp-version=45"
|
Es posible que en algunos procesos tengamos que añadir una variable de entorno LDFLAGS, tipo export LDFLAGS+=' -lomp'
para que la librería de OpenMP proporcionada por LLVM intervenga
en el proceso de enlazado. En paquetes como ImageMagick es necesario
hacer una sustitución masiva después de ejecutar el
script de configuración para sustituir el parámetro -lgomp, añadido de forma automática por el script de configuración, por el parámetro -lomp. Un ejemplo:
$ find . -name 'Makefile' -type f | xargs sed -i 's:-lgomp:-lomp:g' |
Como experiencia personal con algunos paquetes, mi recomendación
es que se utilicen los siguientes parámetros para el uso de esta
optimización.
$ export {C,CXX}FLAGS+=" -fopenmp=libomp -fopenmp-version=50"
$ export LDFLAGS+=" -lomp"
|
En paquetes como LibRaw, si dejamos que el script de
configuración establezca el parámetro -fopenmp por
sí mismo, nos encontraremos que, la librería resultante
del proceso de compilación, no quedará enlazada contra
libomp y, por lo tanto, no hará uso de las
características de esta optimización. En cambio, en otros
paquetes como MAME, sí que funciona este parámetro sin
que tengamos que añadir nada por nuestra cuenta.
NOTA IMPORTANTE= Con Clang 14,
existe un error (inicialmente subsanado, pero que, en las siguientes
versiones de corrección de errores, se ha vuelto a reproducir)
que no añade de forma correcta, el directorio /opt/llvm17/lib64,
a la ruta predefinida de búsqueda de librerías de Clang,
lo que nos obliga a tener que completar la variable de entorno
anterior con lo que está en rojo, siendo obligatorio el uso de
esta variable siempre:
$ export {C,CXX}FLAGS+=" -fopenmp=libomp -fopenmp-version=50"
$ export LDFLAGS+=" -L$(llvm-config --libdir) -lomp"
|
Si no queremos hacer uso de la misma, la otra opción más
simple es crear un enlace simbólico al directorio /usr/lib64 de
la librería libomp:
# ln -s /opt/llvm17/lib64/libomp.so /usr/lib64 |
NOTA IMPORTANTE=
Con Clang 17,
en los paquetes que compilemos con soporte de OpenMP, se
producirá una violación de segmento, si no
añadimos '-ltsan' a la variable de entorno LDFLAGS
correspondiente.
$ export {C,CXX}FLAGS+=" -fopenmp=libomp -fopenmp-version=50"
$ export LDFLAGS+=" -L$(llvm-config --libdir) -lomp -ltsan"
|
Este error nos obliga a tener que añadir esta variable de
entorno LDFLAGS, en todos los procesos de compilación que se
utilice OpenMP en los mismos, a no ser, que esto se solucione en
próximas versiones de corrección de errores del
compilador.
|
PGO |
-fprofile-generate=ruta a directorio o archivo
-fprofile-use=ruta a directorio o archivo |
PGO son las siglas con las que se conoce a la optimización Profile Guided Optimization (Optimización
Guiada por Perfiles). El compilador recopila información
del total de funciones y bloques de datos que contiene el binario
ejecutable, tanto en el proceso de compilación como en una
posterior ejecución del mismo. Dichos datos serán
utilizados en un segundo proceso de compilación, pudiendo
utilizarlos en posteriores procesos de compilación, siempre y
cuando, el código fuente no sea alterado de forma significativa.
La optimización PGO se divide en dos modos:
instrumentación (la que explico aquí) y muestreo, que
requiere del uso de aplicaciones externas como Perf y AutoFDO,
realizando todo el proceso de forma manual por parte del usuario:
ejecución del binario compilado con perf para obtener las
muestras y su posterior conversión con AutoFDO a un formato
legible por Clang.
A diferencia de las otras optimizaciones explicadas en este manual,
ésta requiere de un proceso más elaborado para su
aplicación, que explico a continuación:
1) Creamos un directorio de ubicación de los perfiles de
optimización guiada con permisos de escritura para todos los
usuarios.
$ su
# mkdir -p /var/pgo
# chmod 777 /var/pgo |
2) Establecemos la variable de entorno de generación del perfil
de optimización con la ruta del directorio de perfiles de
optimización que hemos creado, más el nombre del
paquete que vamos a compilar, por ejemplo, mc. Añadimos un nivel
de optimización -O2 y un parámetro de generación de símbolos de depuración, g1 o -gline-tables-only que es lo mismo.
$ export {C,CXX}FLAGS+=' -O2 -g1 -fprofile-generate=/var/pgo/mc |
3) Ejecutamos el script de configuración pertinente y compilamos
el paquete. En la ruta indicada se habrán creado una serie de
archivos de datos con el nombre default_*.profraw.
Instalamos el paquete y lo ejecutamos. Si el paquete de código
fuente contiene tests, lo mejor para recopilar información es
ejecutar en el mismo make check después
de haber compilado el mismo (nos ahorramos tener que instalarlo). En
unos paquetes esto resulta efectivo (por ejemplo, ImageMagick o POV-Ray), en otros, al ser los tests muy básicos, lo mejor es ejecutar la aplicación.
4) Convertimos el formato en crudo de los archivos default_*.profraw a un formato binario legible por Clang, con el comando llvm-profdata:
$ llvm-profdata merge /var/pgo/mc/default_*.profraw \
--output=/var/pgo/mc/default.profdata |
Con la variable de entorno LLVM_PROFILE_FILE, podemos cambiar la ruta
predefinida de ubicación y el nombre del perfil de
optimización. Un ejemplo de ejecución de un programa, en
el que se sustituye el nombre predefinido, por la ID del proceso de
ejecución. Esto nos permitirá crear varios archivos de
perfil por ejecución del programa, que podremos combinar con el
comando llvm-profdata, para su posterior uso en el segundo proceso de compilación del paquete:
$ LLVM_PROFILE_FILE=/var/pgo/mc/mc-%p.profraw mc |
$ llvm-profdata merge /var/pgo/mc/mc-*.profraw \
--output=/var/pgo/mc/default.profdata |
5) Volvemos a recompilar el paquete. Tenemos dos opciones, una es
empezar de cero con las variables de entorno y añadir la
siguiente, volviendo a ejecutar el script de configuración,
después de haber limpiado el directorio de compilación
con el comando make distclean o make clean según esté configurado:
$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/mc |
La otra más rápida consiste en modificar los archivos
Makefile de forma masiva, modificando el parámetro aplicado, con
el siguiente comando:
$ find . -name 'Makefile' | xargs sed -i 's:fprofile-generate:fprofile-use:g' |
Una vez los hayamos modificado, ejecutamos make clean; make y volvemos a instalar el paquete. El
perfil de optimización creado lo podemos cargar de forma directa
en la siguiente compilación, siempre y cuando el código
fuente no haya sido alterado de forma significativa. Ya se
encargará el compilador de avisarnos de esto. Si tenemos
desactivados los avisos con el parámetro -w, no nos
avisará en absoluto.
Tener en cuenta que si creamos el perfil con el parámetro -O2 -g1,
sin ningún tipo de optimización adicional,
obtendremos más información que nos servirá para
aplicar una optimización PGO más efectiva. Lo cual no
quiere decir que no se pueda realizar el proceso con las mismas
optimizaciones en el comienzo y en el final del mismo.
$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/mc |
Para acelerar todo esto, siempre es bueno crearse unas funciones de
Bash. Abrimos con un editor de texto, el archivo ~/.bashrc, si no
existe lo creamos y añadimos lo siguiente al final del mismo:
optclang-gpgo () { dir="$1"; export {C,CXX}FLAGS+=" -O2 -g1 -fprofile-generate=/var/pgo/$dir"; }
optclang-upgo () { dir="$1"; export {C,CXX}FLAGS+=" -fprofile-use=/var/pgo/$dir"; }
optclang-profdata () {
llvm-profdata merge /var/pgo/$1/default_*.profraw
--output=/var/pgo/$1/default.profdata; rm -f
/var/pgo/$1/default_*.profraw; }
|
Guardamos el archivo, abrimos una ventana de terminal, y ahora
simplemente basta ejecutar el alias correspondiente para añadir
la variable de entorno de esta optimización más el nombre
del directorio que definamos para ubicar los datos del perfil.
Primer proceso de compilación:
Conversión de los datos del perfil (incluye borrado de los
archivos generados por el compilador para reducir el espacio en disco
de los directorios que incluyen los perfiles de optimización)
Segundo proceso de compilación:
Y, por último, siempre que se modifiquen los parámetros
de optimización, se debe de crear un perfil nuevo de
optimización porque los resultados pueden variar
significativamente en función de las optimizaciones aplicadas en
el proceso de compilación.
|
CSPGO |
-fprofile-use=ruta a directorio o archivo -fcs-profile-generate=ruta a directorio o archivo
-fprofile-use=ruta a archivo |
Introducida a partir de Clang 9, CSPGO
es una optimización PGO de dos pases, primero se realiza una PGO
normal y, a partir del archivo de perfil creado se vuelve a recompilar
el paquete tomando como referencia dicho archivo, para finalmente,
volver a recompilar el paquete con el archivo de perfil PGO resultante
de la fusión de los archivos de perfil en crudo generados por el
ejecutable (default_*.profraw) y el perfil PGO inicial
(default.profdata). Un ejemplo:
1) Primer proceso de compilación tomando como referencia el archivo de perfil PGO creado en la sección anterior:
$ export {C,CXX}FLAGS+=' -O2 -g1 -fprofile-use=/var/pgo/mc -fcs-profile-generate=/var/pgo/mc |
2) Ejecución y testeo del programa.
3) Convertimos el formato en crudo de los archivos default_*.profraw a un formato binario legible por Clang, con el comando llvm-profdata,
mezclándolos con el perfil PGO creado inicialmente, creando un
archivo de perfil de salida con el nombre de la optimización:
$ llvm-profdata merge /var/pgo/mc/default_*.profraw \
/var/pgo/mc/default.profdata --output=/var/pgo/mc/cspgo.profdata |
4) Finalmente, utilizamos el perfil resultante de la fusión, en el proceso de compilación:
$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/mc/cspgo.profdata |
Para acelerar todo esto, siempre es bueno crearse unas funciones de
Bash. Abrimos con un editor de texto, el archivo ~/.bashrc, si no
existe lo creamos y añadimos lo siguiente al final del mismo:
optclang-csgpgo () { dir="$1"; export {C,CXX}FLAGS+=" -O2 -g1 -fprofile-use=/var/pgo/$dir -fcs-profile-generate=/var/pgo/$dir"; }
optclang-csupgo () { dir="$1"; export {C,CXX}FLAGS+=" -fprofile-use=/var/pgo/$dir/cspgo.profdata"; }
optclang-csprofdata () { llvm-profdata merge /var/pgo/$1/default.profdata /var/pgo/$1/default_*.profraw --output=/var/pgo/$1/cspgo.profdata; rm -f /var/pgo/$1/default_*.profraw; }
|
Guardamos el archivo, abrimos una ventana de terminal, y ahora
simplemente basta ejecutar el alias correspondiente para añadir
la variable de entorno de esta optimización más el nombre
del directorio que definamos para ubicar los datos del perfil.
Primer proceso de compilación:
Conversión de los datos del perfil (incluye borrado de los
archivos generados por el compilador para reducir el espacio en disco
de los directorios que incluyen los perfiles de optimización) y
mezcla con el archivo de perfil PGO. Como opción también
le podemos añadir que borre el archivo de perfil PGO
(default.profdata), para dejar solo el archivo de perfil CSPGO
(cspgo.profdata).
Segundo proceso de compilación:
Por último, si se producieran mensajes de error en la ejecución y testeo del programa, del tipo error: undefined reference to '__llvm_profile_runtime', añadimos la siguiente variable de entorno LDFLAGS en el primer proceso de compilación:
$ export LDFLAGS+=" $(clang -print-resource-dir)/lib/linux/libclang_rt.profile-x86_64.a" |
Esto es válido también para la optimización PGO.
|
Para añadir estas optimizaciones adicionales a las variables de
entorno de optimización de CPU que hayamos establecido, basta
ejecutar el comando siguiente, incluyendo el nivel de
optimización nuevamente, para asegurarnos de que se utilice el
mismo en el proceso de compilación:
Polly
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly' |
Polly (generación automática de código vectorizado)
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine' |
Polly (sólo en aquellos paquetes en los que se active por defecto el parámetro -fopenmp)
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine -mllvm -polly-parallel' |
LTO
$ export {C,CXX}FLAGS+=' -flto'
|
ThinLTO
$ export {C,CXX}FLAGS+=' -flto=thin'
|
En algunos procesos hay que añadir también el parámetro a la variable de entorno LDFLAGS.
$ export {C,CXX,LD}FLAGS+=' -flto=thin'
|
En procesos que se generen librerías estáticas, o intervenga el comando nm de Binutils,
la variable de entorno sería la siguiente, acompañada de
la modificación que sea necesario realizar en paquetes que no
acepten estas variables de entorno.
$ export AR=llvm-ar RANLIB=llvm-ranlib NM=llvm-nm
$ export {C,CXX}FLAGS+=' -flto'
|
Tener en cuenta que el nivel de optimización aplicado en un
proceso de compilación es siempre el último que aparece
en la salida del compilador. Si el script de configuración del
paquete, incluye su propio nivel de optimización, es posible, y
en esta web hay ejemplos, de que éste se muestre detrás
del nivel de optimización que hayamos establecido mediante la
correspondiente variable de entorno en la terminal. Para evitar esto,
tendríamos que recurrir a una edición masiva de los
archivos 'Makefile', con el siguiente comando:
$ find . -name 'Makefile' | xargs sed -i 's:-O2::' |
Para ver las variables de entorno que hemos aplicado antes de ejecutar
el script de configuración, ejecutamos el siguiente comando:
$ echo ${CFLAGS,CXXFLAGS} |
Y si nos hemos equivocado en algo, pues las borramos y volvemos a
empezar. O las sobreescribimos volviendo a aplicar la primera variable
de entorno que hemos establecido, la que no lleva el símbolo '+'.
Clang suele mostrar más mensajes de aviso que GCC, Para
eliminarlos todos (algunos producen errores de compilación),
basta establecer la siguiente variable de entorno, antes de ejecutar el
proceso de configuración del paquete correspondiente.
$ export {C,CXX}FLAGS+=' -w' |
Crear alias de bash para facilitar las tareas de compilación de programas con Clang
Lo mejor que podemos hacer para no tener que estar copiando y pegando variables de entorno relacionadas con Clang,
es automatizar un poco el proceso, creando los correspondientes alias
de bash. A continuación pongo los míos, que cada usuarios
los adapte a sus necesidades. Abrimos con un editor de texto, el
archivo de configuración personal, ~/.bashrc, si no existe lo creamos, y añadimos lo siguiente al final del contenido del mismo:
alias optclang="export CC=clang CXX=clang++ {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3 -mllvm -polly -mllvm -polly-vectorizer=stripmine'"
alias optclang-cpu="export CC=clang CXX=clang++ {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3'"
alias optclang-lto="export {C,CXX}FLAGS+=' -flto'"
alias optclang--thinlto="export {C,CXX}FLAGS+=' -flto=thin'"
alias optclang-ar="export AR=llvm-ar RANLIB=llvm-ranlib NM=llvm-nm"
|
El principal es optclang,
que establece el uso de compilador, optimización de CPU y
optimización con Polly, en un sólo comando. Si nos falla
la compilación con Polly, sobreescribimos este alias con optclang-cpu, que omite la vectorización de código con Polly. Luego como añadido utilizamos el alias optclang-lto para utilizar la optimización LTO o la optimización ThinLTO con el alias optclang--thinlto, que combinamos con el alias optclang-ar
en procesos en los que se compilan librerías estáticas.
Tener en cuenta que todo esto debe de adaptarse al proceso de
compilación en cuestión. Muchas veces tenemos que
añadir el parámetro -flto
a la propia variable de entorno de uso de compilador (export
{CC,CXX}+=" -flto") para que esta optimización se pueda llevar a
cabo con algunos paquetes.
Con el nuevo soporte de OpenMP añadimos un nuevos alias, aunque su uso queda muy reducido por la escases de paquetes que soportan OpenMP.
alias optclang-omp="export {C,CXX}FLAGS+=' -fopenmp=libomp' LDFLAGS+=' -lomp'"
|
|