LLVM (à l'origine Low Level Virtual Machine) est une machine virtuelle principalement destinée à la mise au point des langages informatiques.
Clang est un compilateur basé sur LLVM. Il vise à compiler à la fois le C, C++ et Objective-C. Signe de son actuelle maturité, il devrait être le compilateur C par défaut de FreeBSD 10
Sept mois après la dernière mouture, la suite LLVM sort dans sa version 3.2.
Au programme de nombreuses corrections de bugs et améliorations dans l'optimisation du code, notamment avec une meilleure prise en charge des nouveaux jeux d'instructions , une meilleure vectorisation et enfin, une modification du back-end avec le compilateur Nvidia.
NdM : Merci à Nÿco, Pierre Jarillon, Sylvestre Ledru, Bruno Michel et rewind pour leur participation à la rédaction de cette dépêche.
LLVM
Vectorisation
Une nouvelle vectorisation des boucles a été mise en place. La vectorisation consiste à utiliser des instructions avancées, type MMX ou SSE, qui agissent sur des ensembles de valeurs plutôt qu'une seule valeur à la fois. LLVM disposait déjà d'une vectorisation au niveau des blocs de base, c'est-à-dire que des instructions vectorielles viennent remplacer des ensembles d'instructions localement.
Avec la vectorisation des boucles, il s'agit d'identifier des boucles dont les opérations peuvent être faites en parallèle grâce à des instructions vectorielles. Les premiers benchmarks montrent une accélération entre 2 et 3 fois par rapport à un code normal.
Nouveau backend PTX
Parallel Thread eXecution (PTX) est un langage assembleur créé par NVidia pour CUDA. Il sert d'intermédiaire entre le programme CUDA (un dérivé de C) et le code binaire qui est utilisé par la carte graphique. Le programme nvcc
transforme le code CUDA en assembleur PTX puis le pilote de la carte compile l'assembleur PTX en code binaire.
LLVM permet de générer de l'assembleur PTX. C'est NVidia qui a développé cette partie après avoir fait le choix de LLVM pour leur chaîne de compilation. Ce nouveau backend vient remplacer l'ancien qui était expérimental.
Amélioration de la génération de code
L'ensemble d'instructions vectorielles AVX2 a été amélioré pour les architectures x86 et amd64.
Un assembleur complet pour ARM est maintenant complètement intégré à LLVM.
La génération de code pour les architectures MIPS et PowerPC a été grandement améliorée.
En vrac
La documentation de LLVM est maintenant gérée à l'aide de Sphinx.
Clang
Amélioration des diagnostics
-Wuninitialized
Avec la fonction suivante,
int f(int b) {
int n;
if (b)
n = 1;
return n;
}
L'utilisation de Clang avec l'argument -Wuninitialized produira les messages d'erreur suivants :
$ clang -c -Wuninitialized foo.c
foo.c:3:7: warning: variable 'n' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
if (b)
^
foo.c:5:10: note: uninitialized use occurs here
return n;
^
foo.c:3:3: note: remove the 'if' if its condition is always true
if (b)
^~~~~~
foo.c:2:8: note: initialize the variable 'n' to silence this warning
int n;
^
= 0
1 warning generated.
Attribut tls_model
Le nouvel attribut tls_model
permet de spécifier le modèle mémoire utilisé pour les variables locales à un thread (_Thread-Local Storage_). Cet attribut est spécifique à Clang mais peut être utile pour ceux qui ont des besoins très précis.
Attribut pour la sûreté des types
Certaines API permettent de passer des données à l'aide d'un pointeur générique void*
, tout en précisant le type de données à l'aide d'un paramètre. C'est par exemple le cas pour l'API MPI qui dispose d'un type MPI_Datatype
pour spécifier le type au bout du pointeur.
LLVM permet désormais de pouvoir vérifier si le pointeur passé en paramètre est du bon type par rapport au paramètre de typage. Pour cela, un ensemble d'attributs permet d'identifier quel paramètre est le pointeur et quel paramètre est le type.
Les paramètres des fonctions fcntl()
et ioctl()
sont également gérés de la même manière.
Gestion des commentaires de documentation
Clang permet maintenant, grâce à l'option -Wdocumentation
, de gérer les commentaires de documentation (au format Doxygen) et de s'assurer de leur cohérence avec le code. Voir le compte-rendu de la présentation faite à la Rencontre des développeurs LLVM 2012 à ce sujet.
Prise en charge de C11 et C++11
Clang gère maintenant le mot-clef _Alignof
introduit dans C11. La prise en charge de C++11 est, quant à elle, presque complète, elle s'est vue ajouter la déclaration avancée (_forward declaration_) des enum
.
Debian
LLVM et Clang 3.2 sont aussi déjà disponibles dans Debian.