Structure globale
Transformation de l’AST en un graphe de blocs de base S ´election des instructions
Allocation des registres
Ordonnancement des instructions
Blocs de base
Un bloc de base est une s ´equence d’instructions avec
•
Un seul point d’entr ´ee, au d ´ebut du bloc•
Un seul point de sortie, `a la fin du bloc G ´en ´eralement courtsLes appels de fonction peuvent y apparaˆıtre, selon les cas Une liste d’instructions ponctu ´ee par un branchement
Blocs de base ´etendus
Un bloc de base ´etendu est une s ´equence d’instructions avec
•
Un seul point d’entr ´ee, au d ´ebut du bloc•
Un point de sortie `a la fin du bloc, pas forc ´ement seulDonc, l’extension est de permettre de quitter le bloc en cours de route Encore courts, mais moins que les blocs de base
Une liste d’instructions ponctu ´ee par un branchement D’autres branchments peuvent ˆetre inclus dans la liste
Graphe de flot de contr ˆ ole (CFG)
Un CFG est un graphe dont les nœuds sont des blocs de base Chaque fonction est repr ´esent ´ee par un CFG
Exemple (Source)
struct list { int x; struct list *next; } struct list *list_rev (struct list *l) {
struct list *r = NULL;
while (l) {
struct list *new = malloc (sizeof (struct list));
new->x = l->x;
new->next = r;
r = new;
l = l->next;
}
return r;
Exemple (BBs)
BB0 struct list *r = NULL; goto BB1 BB1 if null l, goto BB3 else goto BB2 BB2 list *new = malloc (sizeof (list));
new->x = l->x;
new->next = r;
r = new;
l = l->next;
goto BB1
Exemple (EBBs)
BB0 struct list *r = NULL; goto BB1 BB1 if null l, goto BB2 else
list *new = malloc (sizeof (list));
new->x = l->x;
new->next = r;
r = new;
l = l->next;
goto BB1
BB2 return r;
Static Single Assignment (SSA)
Repr ´esentation o `u chaque variable n’est affect ´ee qu’ `a un endroit Chaque affectation introduit une nouvelle variable
Chaque BB commence avec des fonction
φ
pour compenser•
E.g.x
9= φ(x
1, x
3, x
6)
Repr ´esentation plus explicite du flot de donn ´ees
D ´ecoupe chaque usage de variable en ´el ´ements ind ´ependants
•
Evite contraintes arbitraires dues `a r ´eutilisation de variable´Exemple (SSA)
BB0 struct list *r0 = NULL; goto BB1
BB1 l1 = phi(l0, l2); r1 = phi(r0, r2);
if null l, goto BB2 else
list *new0 = malloc (sizeof (list));
new->x = l1->x;
new->next = r1;
r2 = new0;
l2 = l1->next;
goto BB1
BB2 return r1;
Conversion vers SSA
Conversion na¨ıve:
•
Ajouter une fonctionφ
pour chaque variable au d ´ebut de chaque BB•
Autant d’arguments que de liens entrant au BB Minimization:•
Eliminer fonctions´φ
de la formex
i= φ(x
a, x
b, x
c, x
d, ...)
o `u
{a, b, c, d, ..} ∈ {i, k}
: Remplacer parx
i parx
k. Nettoyage (pruning):•
Eliminer fonctions´φ
mortesExemple (autre SSA)
BB0() struct list *r0 = NULL; goto BB1(l0, r0);
BB1(l1,r1) if null l, goto BB2() else
list *new0 = malloc (sizeof (list));
new->x = l1->x;
new->next = r1;
r2 = new0;
l2 = l1->next;
goto BB1(l2,r2);
BB2() return r1;
Conversion minimale vers SSA
Dominance stricte: Un nœud A domine strictement un nœud B si on passe n ´ecessairement par A avant B
Dominance: Un nœud A domine un nœud B si A = B ou si A domine strictement B.
Fronti `ere de dominance: Un nœud B est dans la fronti `ere de
dominance d’un nœud A si A ne domine pas B strictement, mais il domine un pr ´edecesseur imm ´ediat de B.
Un nœud de la forme
x = e
n ´ecessitera une fonctionφ
`a l’entr ´ee de chaque BB dans la fronti `ere de dominance de ce nœudArbre de dominance
Dominateur imm ´ediat: nœud qui domine strictement A mais ne domine strictement aucun autre dominateur strict de A.
Dominator Tree: arbre constitu ´e par la relation de dominance
imm ´ediate. Il a pour racine le nœud de d ´epart et chaque nœud a pour enfants les nœuds dont il est le dominateur imm ´ediat
Repr ´esentation efficace: chaque nœud a un champ
idom
IDom
(n) = n→
idomDom
(n) = {n, n→
idom, n→
idom→
idom, ...}
SDom
(n) = {n→
idom, n→
idom→
idom, ...}
A Simple, Fast Dominance Algorithm,
Cooper et.al.Analyse de type forward dataflow:
SDom
(n) =
Tm∈Pred(n) Dom
(m)
for
n ∈
nodes, n→
idom= >;
changed=
true; n
0→
idom= ∅
while changedchanged
=
false forn ∈
nodesidom
=
Tm∈pred(n)
m
ifn→
idom6=
idomn→
idom=
idom;
changed=
trueIntersection efficace de Dom(n)
Num ´eroter en preorder depuis
n
0m ∈
SDom(n) ⇒
PreOrder(m) <
PreOrder(n)
donc Dom
(n)
est naturellement tri ´e:n→
idom< n
inter
n
1n
2=
if n
1= > then n
2else if n
2= > ∨ n
1= n
2then n
1else if n
1< n
2then
intern
1(n
2→
idom)
else
inter(n
1→
idom) n
2Allocation de registres
Analyse de liveness
Cr ´eation du graphe d’interf ´erence Allocation et spilling
Passage d’arguments Coalescing
Simplifications
Analyse de liveness
Analyse de type backward dataflow:
Live-in
(i) = (
Live-out(i) −
Defs(i)) ∪
Use(i)
Live-out
(i) =
Sj∈succ(i) Live-in
(j )
i
est une instructionEnsembles g ´en ´eralement impl ´ement ´es par des bitset
Construction du graphe d’interf ´erences
Parcours simple du control flow graph (CFG)
Interf ´erences entre defs
(i)
et(
Live-out(i) −
Defs(i))
Graphe typiquement repr ´esent ´e par deux structures de donn ´ees redondantes
•
bitmatrix IF, telle que IF(v
1, v
2)
indique s’il y a interf ´erence•
edge sets, o `u ES(v)
liste les variables qui interf `erentAllocation, assignation, et spilling
L’allocation est comparable `a la coloration de graphe Allocation par simplification du graphe d’interf ´erences:
•
Siv
a moins quek
voisins: enlever et ajouter `a la pile•
Sinon, choisir un candidat au spill: enlever et ajouter `a la pile Ensuite, d ´epiler les variables dans l’ordre:•
Si registre disponible, assigner•
Sinon marquer le registre comme spillS’il y a du spill: ajuster le code, et recommencer
Convention d’appel de fonction
Placement des arguments
•
Ajouts d’instructionsmove
Placements des valeurs de retour
•
Ajouts d’instructionsmove
Registres caller-save
•
Interf ´erences entre caller-save et(
Live-out(i) −
Defs(i))
Registres callee-save
•
Ajouts demove t
i:= r
i. . . move r
i:= t
iCoalescing
Elimination des´
move
Ajouter un graphe de pr ´ef ´erences Pref
Durant la simplification du graphe d’interf ´erence:
•
Enlever d’abord lesv
qui ne sont pas dans Pref•
Si Pref(v
1, v
2)
et ils ont (ensemble) moins quek
voisins: coalesce Lors de l’assignation, choisit la m ˆeme couleur si disponibleSpilling
Choix des variables `a spill:
•
Co ˆut estim ´e de placer la variable en m ´emoire•
Probabilit ´e que faire ce spill dev
´evite d’autres spill Choix possible:Value
(v) = |
ES(v)|
Cost
(v)
Possibilit ´e aussi de faire du splitting
•
Divise la variable en deux et ajoute unmove
entre les deux•
Peut parfois ´eviter le spillSimplifications
Au lieu de tout recommencer, apr `es un spill:
•
Mettre `a jour le graphe d’inf ´erence•
R ´esultat conservateurAllocation de registres en SSA
SSA augmente le nombre de variables mais simplifie le graphe:
•
Clique de taille N⇒
N variables live simultan ´ement!•
Coloration optimale: greedy par pr ´e-ordre du dominator tree S ´eparation d’allocation et assignation•
Ajout de spill pour r ´eduire taille max de live-set– Cons ´equences et gains de chaque spill imm ´ediatement visibles!
•
Choix de couleur affecte seulement le coalescing – Choix optimal de coalescing co ˆuteux: NPLinear Scan Allocation
Allocation de registres tr `es rapide, quoique moins bonne Algorithme classique ans les compilateurs JIT
Ordonne toutes les instructions
•
Choix de l’ordre affecte le r ´esultatForces chaque live-range `a ˆetre un intervalle contigu
•
Approximation conservatriceAllocation greedy en traversant le code lin ´eairement
•
S’il n’y a plus de registres, spill le live-range le plus longOrdonnancement d’instructions
Rapprocher les instructions ind ´ependentes
•
Exploiter le parall ´elisme de type ILP Eloigner les instructions´ d ´ependentes•
Eviter d’attendre le r ´esultat d’une longue op ´eration´ Bloc de base = graphe acyclique de flot de donn ´ees•
Ordonnancement est un encodage s ´equentiel•
Processeur OOO re-d ´ecode ensuite en un graphe de flot de donn ´eeD ´ependances
RAW (Read After Write): vrai d ´ependance
WAR (Write after Read): anti-d ´ependance; lire avant de perdre WAW (Write After Write): d ´ep. de sortie; perdre la bonne ´ecriture
¡Attention aux exceptions!
SSA ne garde que les d ´ependances vraies
Allocation de registres r ´e-introduit de fausses d ´ependances Construction de graphe de d ´ependances:
•
Graphe orient ´e•
Chaque ar ˆete porte la latence associ ´eeOrdonnancement du graphe
L’ordonnancement est un tri topologique: