• [^] # Re: OpenBSD utilise gcc 3.3. Les nazes.

    Posté par . En réponse au journal Fin de gcc dans les *BSD ?. Évalué à 10.

    J'ai un peu de temps, je vais donc enfoncer quelques portes ouvertes.

    ***

    Tout d'abord, rappelons que gcc a été l'un des premiers compilateurs C sous licence libre. Et quand je dis "l'un des premiers", soyons sérieux un instant, il n'existait que _deux_ compilateurs libres : pcc, qui était quasiment abandonné sans que personne ne reprenne le navire, et gcc.

    Les autres compilateurs étaient non libres (comme lcc) ou n'ont pas réussi à se faire connaître aussi bien que gcc (souvent parce que leur cible n'étaient pas les systèmes de type Unix).

    Gcc 1 a donc eu un boulevard pour se développer, et a tout naturellement capté les meilleures compétences. Le vide s'est fait petit à petit, avec les compilateurs propriétaires (mipspro, Sunpro, XLC, etc) d'un côté et gcc de l'autre.

    À cette époque, on est encore à la fin des années 1980, les systèmes libres ne pèsent rien du tout.

    Un certain Michael Tiemann adapte gcc pour le support du C++ lors de sa thèse à l'INRIA, ce qui provoque l'éclatement de gcc 1 en une conception plus modulaire permettant de gérer plusieurs languages : gcc 2 est né. Tiemann fonde Cygnus dans la foulée.

    Vous suivez toujours ? Gcc 2 sort au début de l'année 1992. À cette époque, on commence seulement à avoir des compilateurs C++ solides, qui ne sont plus des compilateurs C avec une surcouche comme l'était CFront, et qui peuvent enfin gérer les constructions les plus complexes que permet le language.

    Afin d'aider à asseoir la notoriété et l'utilisation de gcc (et surtout de g++), Richard Stallman impose que les deux parties de gcc (celle qui traduit un des langages supportés en la représentation interne RTL, et celle qui traduit le RTL en du code assembleur) ne puissent pas être disjointes, de façon à ce qu'un vendeur de compilateur propriétaire ne puisse pas utiliser par exemple l'analyseur syntaxique C++ de gcc 2, et mettre son propre générateur de code assembleur derrière.

    C'est un choix qui va à l'encontre de la philosophie Unix (qui favoriserait ``gcc-highlevel monfichier.c | gcc-lowlevel | as -o monfichier'' avec un gcc en deux composants distincts), mais qui est compréhensible dans l'optique "pénaliser le code propriétaire à tout prix" du projet GNU.

    Par contre, d'un point de vue d'ingénieur, c'est une décision regrettable, ne serait-ce que pour déboguer : tu peux demander à gcc de te "cracher" 30 fichiers de représentation intermédiaire correspondant à 30 étapes d'optimisation, mais tu n'as aucun moyen, lorsque tu crois avoir détecté une erreur à la passe N, de modifier manuellement ce fichier et de le réinjecter à la passe N+1, afin de vérifier ton hypothèse dans le code final.

    C'est sur ce point que râle perpétuellement Marc Espie (la partie "perverted design").

    ***

    Un autre reproche, peut-être plus spécifique à OpenBSD, est le choix des plate-formes supportées par gcc. Gcc évolue de plus en plus vite, c'est bien (et ça change du cycle de release entre 2.5.8 et 2.8...), mais du coup il est difficile de suivre quand tu as d'autres choses à faire à côté. Les développeurs de gcc ne testent pas tous toutes les plate-formes pour lesquelles gcc est capable de produire du code (que ce soit en natif ou en compilation croisée), et le résultat est que sur les N plate-formes supportées par gcc, seule une bonne moitié est vraiment fiable, les autres souffrant de bugs par ci par là, qui peuvent très bien être indétectés avant belle lurette, ou produire des erreurs subtiles dans le comportement d'un programme difficile à analyser.

    Il y a plusieurs plate-formes où, par manque d'intérêt ou de gens payés pour, le "backend" de gcc est fiable en version N, mais plus en version N+1, soit à cause de bugs bêtes, soit parce que les optimisations plus fines de cette nouvelle version de gcc cassent certaines choses "considérées comme acquises" (comment traduire ``assumptions'' ?) par le code du backend. Pire encore, le backend peut être mal écrit initialement et mal décrire la réalité du processeur.

    Dans ce cas, il y a un travail important à accomplir, et de nos jours, à la vitesse où sont introduits dans gcc des changements (nouvelle représentation intermédiaire, nouvelles optimisations, nouveau modèle de gestion du parallélisme) nécessitant des modifications substancielles du backend, il n'est pas possible de suivre si l'on ne dispose pas de beaucoup de temps à consacrer à gcc.

    On le voit très bien dans les changelog de gcc ou les backend sont de facto en deux classes : ceux qui sont maintenus, souvent par des personnes payées à plein temps pour le faire par IBM, Apple, Sony ou autres, et ceux pour lesquels les seuls changement visibles sont des changement systématiques (remplacement de VIEIILLE_MACRO() par NOUVELLE_MACRO(), correction de fautes d'orthographe dans les commentaires, extension du copyright à la nouvelle année tous les ans) dont il a simplement été vérifié de temps en temps qu'ils compilent, et aucune autre activité.

    C'est une source de mécontentement croissante, parce que justement cela montre que gcc (et plus particulièrement gcc 4) peut de moins en moins être présenté comme supportant autant de plate-formes que par le passé.

    ***

    Le troisième reproche fait à gcc est la lenteur croissante des temps de compilation.

    Autant les migrations successives de 2.1 à 2.95 ont conservé des temps de compilation proches, autant chaque version intermédiaire de gcc 3 a impacté les temps de compilation de façon significative (30 à 70% selon les plate-formes, pour un passage de 2.95 à 3.3, les plate-formes le plus affectées étant celles disposant de beaucoup de registres : alpha, hppa, mips, sparc).

    Heureusement, 4.1 puis 4.2 commencent à bien digérer le passage à la représentation ssa, et regagnent du temps sur 3.4 (on constate généralement des temps intermédiaires entre ceux de 3.3 et ceux de 3.4, lorsque l'on compile avec 4.2).

    Mais, comme je le disais un peu plus haut, il arrive que le support d'une architecture donnée soit absent ou non fiable en 4.x. Voire en 3.x. Donc, faute de moyens (essentiellement en temps), on en reste à gcc 2.95.

    Le fait que les développeurs de gcc ne soient pas intéressés pour aider à migrer un backend 2.95 au niveau 3.4 ou 4.x, n'aide pas non plus à la motivation.

    ***

    On en vient alors à "mais s'ils sont aussi mécontents de gcc, qu'ils utilisent donc autre chose !".

    Oui, on aimerait bien. D'ailleurs on y pense depuis longtemps, et plusieurs développeurs OpenBSD s'étaient intéressés à TenDRA il y a moult années déjà.

    Mais comme je l'ai rappelé plus haut, gcc a fait le vide autour de lui. TenDRA, par exemple, n'était plus maintenu depuis la fin des années 1990, et le groupe qui s'est monté pour le reprendre a surtout réussi à se tirer dans les pattes et à se scinder en deux groupes encore moins actifs.

    Ce qui fait la différence dans pcc, c'est qu'il est plus facile de "rentrer" dans le code que dans celui de TenDRA, et que les projets BSD ont de très bonnes relations avec Ragge (Anders Magnusson) à l'origine du renouveau de pcc.

    La situation est donc différente : ce n'est plus reprendre un projet dont l'équipe a mis la clef sous la porte, mais c'est s'injecter dans un projet bouillonnant, et qui n'intéresse d'ailleurs pas qu'OpenBSD : sur la liste de développement de pcc, on trouve aussi des gens de DragonflyBSD et NetBSD.

    ***

    Je terminerai en rappelant qu'il est évident qu'il reste beaucoup de travail à accomplir. Pcc n'est pas près de remplacer gcc dans OpenBSD, mais on va essayer de le faire mûrir pendant quelques mois, afin de voir quel effort est réellement nécessaire pour obtenir une alternative viable à gcc.

    Ceux qui s'imaginent que c'est pour demain sont de doux rêveurs... tout comme ceux qui s'imaginent que c'est une tâche impossible.