Vous êtes sur la page 1sur 78

1

2
3
4
Dans ce cours, nous n'allons voir que les optimisations indépendantes de la machine.
Historiquement, se sont toutes les optimisations qui réduisent le nombre d'instructions
exécutées.
Hélas, les processeurs modernes sont devenus tellement sophistiqués (introduction du
parallélisme et des méthodes d’exécution spéculatives), que beaucoup de ces
optimisations sont devenus obsolètes. Mais personne n'a le courage, la motivation, le
temps et l'argent pour réécrire un compilateur performant en partant de zéro en réécrivant
toutes les bonnes veilles techniques d'optimisation.

5
6
7
8
Les utilisateurs mal avertis tentent
d’optimiser automatiquement tout le
code sans discernement ! Si un logiciel
est très gros, l’optimiser tout
entièrement sans chercher à détecter
les parties « chaudes » est un effort
fastidieux et futile.

9
10
11
12
13
14
15
16
17
Cependant, un appel de procédure peut paraître librement à l'intérieur d'un bloc de base
(en supposant qu’il y a toujours un retour à l'appelant)

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Analyse le flot de données dans le cas des scalaires et des registres est simple car on
connaît précisément l'emplacement mémoire où est stockée l'information. Pour savoir s'il
existe un flot de données entre i1 et i2, il suffit de vérifier si i1 écrit dans une variable lue
par i2.

33
si on prend on comptes les branchements, une variable x peut être définie dans plusieurs
endroits du programme. Dans certains cas, on sait déterminer avec exactitude quels sont
les définitions qui ne sont pas visibles à un point donné (exemple à droite).

34
Il existe plusieurs méthodes sophistiquées permettant l'analyse des dépendances de
données entres les variables appartenant à un tableau. Paul Feautrier, un ancien
professeur de l’UVSQ puis de l’ENS-Lyon fut un célèbre chercheur dans ce domaine.

35
Déterminer l'existence de flots de données en prenant en compte les pointeurs est très
difficile (indécidable dans le cas général). Elle s'effectue souvent après l'analyse d'alias
(alias analysis) : c'est une analyse de code qui permet de déterminer vers quels variables
pointent chaque pointeur.

36
37
38
39
L'élimination des sous expressions communes peut transformer un arbre en DAG. Bien
que l'on ait réduit le nombre d'opérations à exécuter, les DAGs compliquent la tâche du
compilateur pour optimiser les registres. Ainsi, on risque de générer du spill qui dégrade
les performances.
L'élimination des sous expressions communes fonctionnent très bien pour les expressions
des calculs d'adresse pour les éléments des tableaux.

40
41
42
Cet algorithme donne un ordre d'évaluation des nœuds d'un DAG. Cet ordre n'est pas
optimal mais tente de réduire la consommation en registres. L’ordre final d’évaluation du
DAG est l’ordre inverse du listing. Voir exemple juste après.

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
Le besoin en registres de cet ordre d'évaluation peut dépasser le nombre de registres
disponibles. Dans ce cas, on insère du spill.

60
61
Une génération automatique de code peut engendrer des calculs stupides, redondants, etc.
Les optimisations à lucarne sont des techniques simples permettant de limiter les dégâts.

62
63
L'instruction if peut être éliminée car la condition est évaluée à faux statiquement par le
compilateur.

64
Toute instruction qui suit immédiatement un goto est éliminée (sauf si elle est
étiquetée).

65
Une propagation de constante peut révéler du code inaccessible.
Aussi, éliminer du code inaccessible permet de supprimer des branchement, facilitant
ainsi la propagation de constante.

66
67
68
69
70
71
72
73
La propagation de copie ne traite pas uniquement la propagation de constantes, mais bien
des variables.

74
75
76
77
78

Vous aimerez peut-être aussi