– ´emission de code (codegen.scm)
– allocation de registres & gestion des d´ebordements de registres
2 Structure du compilateur
Le compilateur g`ere les programmes sous cinq formes : code source, ASA
typ´e, IR1, pseudo assembleur avec pseudo-registres, et pseudo assembleur avec
registres allou´es.
Le code source est transform´e en ASA (non-typ´e) via sexp->node. Cet ASA
est ensuite typ´e par annotate-node.
IR1 (typ´e) permet principalement d’effectuer les analyses plus ais´ement en
transformant l’arbre expression de l’ASA en des s´equences explicites d’instruc-
tions (impures) et d’expressions (pures). L’ASA est na¨ıvement transform´e vers
IR1 par ast-to-ir1. Certaines simplifications de base sont ensuite effectu´ees
par simplify-ir1 pour clarifier l’IR1. Cependant, il est important de noter que
l’IR1 n’est pas encore complet : des expressions ´egales peuvent ´evaluer `a des va-
leurs diff´erentes `a l’ex´ecution, puisqu’il y existe aussi des instructions impures
(assignations, ´ecriture sur des tableaux). C’est pourquoi annotate-effects an-
note chaque sous-expression de lecture une liste de d´ependances (instructions
qui affectent la valeur de la lecture). Ainsi, on garanti que deux expressions
´equivalentes ´evaluent `a la mˆeme valeur `a l’ex´ecution.
ast-to-ir1 ´emet du code tr`es simpliste, o`u chaque expression ne repr´esente
qu’une seule op´eration. Afin de pallier `a ce probl`eme et obtenir de plus grandes
expressions, forward-assignments remplace le plus possible les lectures de va-
riables par la derni`ere expression assign´ee `a cette variable. On peut alors ´eliminer
plusieurs assignations inutiles, et mˆeme certaines variables compl`etement in-
utilis´ees `a l’aide de elimination. Cela expose aussi de plus grandes expres-
sions aux optimisations alg´ebriques, de calculs constants et de canonicalisation
(optimize-all-expressions).
L’IR1 contient des sections par, o`u l’ordre d’´evaluation des instructions est
laiss´e libre au compilateur. Il est essentiel, avant de compiler pour une machine
r´eelle, de fixer l’ordre d’´evaluation. Une fois les expressions d’indexation sim-
plifi´ees et canonicalis´ees, il est souvent possible de comparer les indices dans
les acc`es aux tableaux. On peut utiliser cette information pour ordonner les
instructions afin d’obtenir des ordonnancements qui donnent lieu `a des acc`es
m´emoire en flux lin´eaire (autant que possible). reorder-all-pars transforme
les sections par en des s´equences d’instructions lin´eaires avec une heuristique
pour atteindre des acc`es en flux dans les cas communs.
On peut ensuite r´eoptimiser le r´esultat de l’ordonnancement explicite (l’ex´ecu-
tion ´etant mieux d´etermin´ee, on a acc`es `a plus d’information). Dans le code
actuel, l’IR1 n’est que simplifi´e et annot´e pour les d´ependances.
La g´en´eration de code se fait en deux ´etapes. emit-statements transforme
l’IR1 (sans par) en une liste d’instructions de niveau assembleur (`a trois re-
2