Compilateurs
Apprenez le fonctionnement des compilateurs avec des QCM : analyse lexicale et syntaxique, représentations intermédiaires en forme SSA, optimisations comme la propagation de constantes et le déroulage de boucles, allocation de registres.
Compilateurs : points clés
Un compilateur traduit les programmes écrits par des humains en code machine exécutable par un CPU. Il passe par l'analyse lexicale, qui découpe le code source en tokens, l'analyse syntaxique, qui construit un arbre selon la grammaire, et l'analyse sémantique, qui vérifie types et noms, avant de convertir le programme en représentation intermédiaire (IR).
Sur l'IR, il applique des optimisations comme la propagation de constantes (constant folding), l'élimination des sous-expressions communes, l'inlining, le déroulage de boucles et la vectorisation, puis génère un code adapté au CPU par allocation de registres et ordonnancement des instructions. Comprendre ces optimisations aide à écrire du code rapide et à tirer le meilleur parti du matériel.
Toutes les questions sur Compilateurs (50)
- Quel est le rôle de l'analyse lexicale d'un compilateur ?
- Que fait l'analyse syntaxique d'un compilateur ?
- Quel exemple d'erreur détectée par l'analyse sémantique d'un compilateur est le plus approprié ?
- Quelle caractéristique de l'arbre syntaxique abstrait (AST) est correcte ?
- Quel est le principal avantage d'utiliser, à l'intérieur d'un compilateur, une représentation intermédiaire (IR) indépendante du langage source comme du CPU ?
- Quelle définition du bloc de base est correcte ?
- Dans un graphe de flot de contrôle, quelle combinaison de ce que représentent nœuds et flèches est correcte ?
- Quelle caractéristique d'une représentation intermédiaire en forme SSA est correcte ?
- Mis en forme SSA, le code ci-dessus comporte après l'instruction if une expression du type « x3 = φ(x1, x2) ». Quel est le rôle de cette fonction φ ?
- Quel exemple de repliement de constantes (constant folding) est correct ?
- En appliquant de façon répétée la propagation et le repliement de constantes au code ci-dessus, quel code obtient-on finalement ?
- Quelle description de l'élimination des sous-expressions communes appliquée au code ci-dessus est correcte ?
- Qu'élimine la suppression de code mort (dead code elimination) ?
- Quelle combinaison d'avantage et d'inconvénient de l'expansion en ligne (inlining) des fonctions est correcte ?
- Quel est le principal effet du déroulage de boucle (loop unrolling) ?
- Dans la boucle ci-dessus, quel calcul est concerné par le déplacement d'expression invariante de boucle (sortie de la boucle) ? (x et y ne sont pas modifiés dans la boucle)
- Dans la boucle ci-dessus, quelle transformation correspond à la réduction de force appliquée au calcul d'indice i * 4 ?
- Quelle est la principale raison pour laquelle la boucle ci-dessus est difficile à vectoriser avec des instructions SIMD ?
- Dans la fonction ci-dessus, pourquoi le compilateur ne peut-il pas, en l'état, sortir de la boucle la lecture de *b ?
- Pour l'allocation de registres par coloration du graphe d'interférence, quelle combinaison de ce que représentent nœuds et arêtes est correcte ?
- Lorsqu'un « déversement » (spill) se produit lors de l'allocation de registres, qu'advient-il du code généré ?
- Quel est le principal objectif de l'ordonnancement des instructions par le compilateur ?
- Quel effet produit l'optimisation des appels terminaux appliquée au dernier appel récursif de la fonction ci-dessus ?
- Quelle différence entre compilateur et interpréteur est correcte ?
- Quelle caractéristique d'un environnement d'exécution utilisant la compilation JIT est correcte ?
- Quelle est l'architecture de base de LLVM ?
- Dans quelle situation utilise-t-on souvent l'option de niveau d'optimisation désactivant l'optimisation (-O0, etc.) ?
- Quelle définition de l'optimisation guidée par profil (PGO) est correcte ?
- Quelle optimisation l'optimisation à l'édition de liens (LTO) rend-elle possible ?
- En C, le débordement d'un entier signé est un comportement indéfini. Sur cette base, quel code un compilateur optimisant la fonction ci-dessus peut-il générer ?
- Parmi les erreurs de programme, laquelle peut être détectée dès la compilation ?
- Dans un langage à typage statique, quel est le principal avantage de la vérification des types par le compilateur ?
- Qu'utilise-t-on souvent pour exprimer les règles de reconnaissance des lexèmes dans l'analyse lexicale ?
- Quel type de grammaire, utilisé pour décrire la grammaire de nombreux langages de programmation, sert de base à l'analyse syntaxique ?
- Quelle est la forme correcte de l'arbre syntaxique abstrait de l'expression 2 + 3 * 4 ?
- Quelle caractéristique du code à trois adresses, l'une des représentations intermédiaires, est correcte ?
- Que détermine l'analyse de vivacité (liveness), effectuée en préparation de l'allocation de registres ?
- Dans une fonction, le nombre maximal de valeurs vivantes simultanément est de 5. Dans le cas simple où le graphe d'interférence ne crée pas d'autre contrainte que ces 5 valeurs, combien de registres faut-il au minimum pour placer toutes les valeurs en registre sans déversement ?
- Si une boucle de 100 itérations est réécrite par déroulage avec quatre copies du corps, combien y a-t-il de tests de comptage et de branchements ? (100 est divisible par 4)
- Quel est l'enchaînement courant permettant d'obtenir un exécutable à partir d'un programme C ?
- Comment appelle-t-on l'optimisation qui examine par une petite fenêtre de courtes séquences du code machine généré pour remplacer des combinaisons d'instructions inefficaces par de meilleures instructions ?
- Dans le code ci-dessus, quelle optimisation s'applique ensuite après l'expansion en ligne de sq, et avec quel résultat ?
- Quelle définition du pipeline logiciel (software pipelining) est correcte ?
- Pourquoi un compilateur, sous réglage strict, ne réordonne-t-il pas de lui-même l'addition en virgule flottante (a + b) + c en a + (b + c) ?
- Quel type d'instructions la vectorisation automatique du compilateur utilise-t-elle ?
- Quelle condition fondamentale les optimisations du compilateur doivent-elles respecter ?
- Quelle définition de la sélection d'instructions, l'une des étapes de la génération de code, est correcte ?
- Quelle définition du compilateur croisé est correcte ?
- Lorsqu'on examine au débogueur un programme compilé avec optimisation, certaines variables apparaissent parfois comme « non affichables ». Quelle en est la principale raison ?
- Après application poussée de la propagation de constantes, du repliement de constantes et de la suppression de code mort à la fonction ci-dessus, quelle valeur renvoie la fonction et quel code subsiste ?
Comparatifs sur ce thème
Autres thèmes de Systèmes informatiques
- Arithmétique des ordinateurs IEEE 754, virgule fixe, erreur d'arrondi
- ISA et assembleur RISC-V, modes d'adressage, conventions d'appel
- Éditeurs de liens, chargeurs et exécutables ELF, symboles, relocalisation, liaison dynamique
- Système d'exploitation et matériel Interruptions, appels système, défauts de page
- Hiérarchie mémoire Cache, remplacement, trois types de défauts
- Multicœur et synchronisation MESI, instructions atomiques, barrières mémoire
- Programmation GPU Warps, mémoire partagée, coalescence, occupation
- Pile matérielle et logicielle de l'IA Inférence/entraînement, quantification, roofline
- Systèmes embarqués et firmware GPIO, UART/SPI/I2C, RTOS
- HDL et vérification Verilog, latches, machines à états, testbenches
- Interfaces d'E/S et bus PCIe, USB, SerDes, CXL
- Analyse des performances Loi d'Amdahl, CPI, goulots d'étranglement
- Sécurité matérielle Canaux auxiliaires, secure boot, TEE, PUF
- Gestion de l'énergie DVFS, power gating, états de veille