• Aucun résultat trouvé

VII. Optimisation de code La phase de l’

N/A
N/A
Protected

Academic year: 2022

Partager "VII. Optimisation de code La phase de l’"

Copied!
13
0
0

Texte intégral

(1)

Page

La phase de l’optimisation est facultative car elle n’intervient en aucune façon dans le processus de traduction.

L’optimisation du code objet revient à déterminer le plus petit code du point de vue taille qui s’exécute le plus rapidement possible. La complexité de ce problème est la cause primordiale de l’inexistence d’une solution à se problème.--> juste une amélioration en terme d’espace mémoire et temps d’exécution.

Les opérations d’optimisation peuvent être entreprises à tout moment, le long du processus de compilation et même avant celui-ci, c’est à dire pendant la tache de programmation,

Pour ce chapitre, le processus d’optimisation est effectué après la génération du code intermédiaire.

Il existe plusieurs différentes opérations d’optimisation, parmi ces opérations, nous citons : -emploi optimal des registres dans les instructions du code objet : la bonne gestion des registres - optimisation des boucles :réduire le temps d’exécution des boucles influencera énormément sur le temps total d’exécution du programme.

- Optimisation des sous expressions communes :

- optimisation locale : remplacer le code : if a <= b goto l1 goto l2 L1 : par if a>b goto l2 l1 : 1 Optimisation des boucles :

Avant d’entamer ce type d’opération, il est nécessaire de savoir détecter les boucles d’un code intermédiaire pour rendre plus complet le processus d’optimisation, la procédure de détection des boucles d’un code nécessite la connaissance de plusieurs notions à savoir les blocs fondamentaux. Ces notions vont nous permettra de construire un graphe appelé graphe de flot de contrôle :

1.1 Trouver les leaders :

Un leader est une instruction particulière du code obéissant à la définition suivante : - La première instruction du code est un leader.

- Toute instruction qui suit dans l’ordre d’apparition des instructions une instruction de branchement conditionnel est un leader.

- Toute instruction dont le numéro du quadruplet figurant comme la cible d’une instruction da branchement conditionnel ou inconditionnel est un leader.

Exemple : considérons le code intermédiaire du programme suivant : P :=0 ; i := 1 ; While i<= n begin p := p + a[i] *b[i] ; i:= i + 1 ; end ;

1: p:= 0 2: i:=1

3:if I<= n goto 5 4:goto 17 5:t1:= I *3 6: t2:= a-3 7: t3:= t2[t1]

8 :t4 := i*3 9 : t5 := b – 3

Les leaders de ce code sont les quaduplets dont les numéros sont : 1,3,4 et 5 1.2 Partitionnement en blocs fondamentaux :

Un bloc fondamental est une séquence d’instructions débutant avec un leader et s’achevant à l’instruction qui précède le prochain leader.

En appliquant cette règle sur l’exemple précédent nous trouvons les blocs B1, B2 , B3 et B4 suivants : B1

B2

B3 B4

10 :t6 := t5[ t4]

11 :t7 :=t3 * t6 12 : t8 := p + t7 13 : p := t8 14 : t9 := i+ 1 15 : i := t9 16 : goto 3 17 :

1: p:= 0 2: i:=1

3:if I<= n goto 5

4:goto 17

5:t1:= I *3 6: t2:= a-3 7: t3:= t2[t1]

8 :t4 := i*3 9 : t5 := b – 3 10 :t6 := t5[ t4]

11 :t7 :=t3 * t6 12 : t8 := p + t7 13 : p := t8 14 : t9 := i+ 1 15 : i := t9 16 : goto 3

(2)

Page 79 1.3 Construction du graphe de flow de contrôle :

Les blocs fondamentaux représentent les nœuds du graphe de flow , il reste de créer les arcs du graphe.

Un arc n’existera entre un bloc Bi et un bloc Bj que lorsque le leader de Bj est susceptible de suivre la dernière instruction de Bi au moment de l’exécution :

Le graphe de flow obtenu pour notre exemple est donc :

B1 B2

B3

B4

A partir de ce graphe nous allons détecter les boucles du code intermédiaire. Nous définissons une boucle comme étant un sous ensemble de l’ensemble X1,X2, …Xn des blocs fondamentaux tel que :

1) Pour toute paire ( Xi, Xi+1) il existe un arc de Xi à Xi+1 2) Il existe un arc de Xn à X1

3) Il existe un prédécesseur de X1 autre que Xn

Dans le graphe de la figure précédente, la seule boucle qui existe est ( B2 , B4).

-maintenant que la boucle est déterminée, nous pouvons améliorer le code en lui faisant subir les opérations suivantes :

- déterminer le code invariant puis le déplacer à l’extérieur de la boucle.

- chercher les variables d’inductions et les éliminer pour n’en garder qu’une seule.

- diminuer la puissance de certains opérateurs.

1.4 Déplacement du code invariant :

Un code est invariant à l’intérieur d’une boucle lorsque pour toutes les itérations de la boucle, son calcul ne varie pas.

Dans notre exemple :le calcul des instructions : 6: t2:= a-3 et 9 : t5 := b – 3 du bloc B4 ne change pas lors des différentes itérations de la boucle , alors il convient à déplacer ce code à l’extérieur de la boucle, nous allons donc créer un autre bloc nommé B’2 formé de ce code et le placer juste avant B2.

1: p:= 0 2: i:=1

3:if I<= n goto 5 (B4)

4:goto 17 (B5)

5:t1:= I *3 6: t2:= a-3 7: t3:= t2[t1]

8 :t4 := i*3 9 : t5 := b – 3 10 :t6 := t5[ t4]

11 :t7 :=t3 * t6 12 : t8 := p + t7 13 : p := t8 14 : t9 := i+ 1 15 : i := t9

16 : goto 3 B(2)

Une structure adéquate pour représenter un graphe de flow peut être un tableau dont chaque élément est constitué d’un enregistrement contenant les

informations suivantes : - Le bloc fondamental

- Les successeurs du bloc fondamental - Les prédécesseurs du bloc fondamental

- Les numéros des instructions du bloc fondamental.

La structure du graphe de flow précédent est :

Bloc Instructions Préd succ

B1 (1,2) 0 (B2)

B2 (3) B1 B3,B4

B3 (4) B2 B5

B4 (5…..16) B2 B2

p:= 0 i:=1 t2:= a-3 t5 := b 3 if I<= n goto B4 goto B5 t1:= I *3 t3:= t2[t1] t4 := i*3 t6 := t5[ t4] t7 :=t3 * t6 t8 := p + t7 p := t8 t9 := i+ 1 i := t9 goto B2

(3)

Page 1.5 Variables d’induction :

Deux variables x et y sont dites d’induction si on peut déduire les valeurs de x à partir de celles de y et vis versa.

Dans le bloc B4 de l’exemple précédent, nous pouvons remarquer que les variables i, t1 et t4 sont des variables d’induction : t1= i*3= t4 t2= i* 3= t1 i= t1/3= t4/ 3

En conséquence nous pouvons éliminer toutes les variables d’induction pour n’en garder qu’une seule.

Cependant une précaution est à prendre concernant les variables à éliminer, il faut s’assurer que dans la suite du code la variable à éliminer ne vit pas, En admettent que les variables t1 et i ne vivent pas dans la suite du code, en les éliminant nous obtenons le graphe suivant :

1.6 : Réduction de la puissance des opérateurs :

Un opérateur OP1 est plus puissant qu’un opérateur OP2 lorsque l’implémentation de OP1 est plus complexe que celle de OP2. Par exemple, l’opérateur de multiplication est plus puissant que l’opérateur d’addition l’implémentation câblée de la multiplication est basée sur un circuit logique plus couteux qu’un additionneur et parfois utilisant plusieurs additionneurs. De même le programme software implémentant la multiplication utilise des opérations d’addition.

Le temps d’exécution de l’opérateur OP1 est donc plus important que celui de OP2.

Si l’on parvient à substituer un opérateur moins puissant à un opérateur d’une instruction appartenant à une boucle, nous réduirons de beaucoup le temps de calcul de la boucle.

Nous avons auparavant remplacé l’instruction t1 := i * 3 par l’instruction t4 := t4 + 3

Cette substitution a entrainé involontairement le changement de m’opérateur de multiplication en l’opérateur d’addition.

p:= 0

t2:= a-3 t5 := b – 3

T4:= 0

t9:= 3*n t10:= t9 - 3 if t4<= t10 goto B4

goto B5

t4 := t4 +3 t3 := t2[t4]

t6 := t5[ t4]

t7 :=t3 * t6 t8 := p + t7 p := t8 goto B2

Toute instruction faisant figurer la variable i ou t1 a été remplacée par une autre instruction équivalente ne contenant pas les variables i et t1.

En abolissant les variables i et t1, nous gagnerons de l’espace mémoire alloué à ces variables et dans certains cas du temps de calcul et ceci en éliminant des instructions.

(4)

Page 81 2. Optimisation des sous expressions communes :

A l’intérieur d’un même bloc fondamental, nous pouvons avoir une situation telle que plusieurs instructions se trouvant à des endroits distincts assument le même calcul. Tel est le cas dans le bloc B4 pour les instructions : t1 := i *3 et t4 := i*3

Nous pouvons remarquer que l’instruction t4 := i*3 est tout à fait inutile dans le bloc B4, elle peut être éliminée si t4 ne vit pas dans la suite du code .

La variable T4 figurant dans toute autre instruction sera remplacée par t1.

La construction d’un DAG à partir des instructions à trois adresses est une bonne façon de déterminer les sous expressions communes à l’intérieur d’un bloc, de déterminer quels noms sont utilisés à l’intérieur d’un bloc mais évalués à l’extérieur, et de déterminer quels résultats des instructions d’un bloc peuvent être utilisés à l’extérieur de ce bloc.

Un DAG pour un bloc de base est un graphe orienté acyclique dont les nœuds sont étiquetés comme décrit ci-dessous :

1- les feuilles sont étiquetées avec des identificateurs uniques qui sont soit des noms de variables soit des constantes, les feuilles représentent les valeurs initiales des noms, et nous les indiçons avec la valeur 0 pour éviter la confusion avec les autres étiquettes.

2- les nœuds internes sont étiquetés par un symbole d’opérateur.

3- On peut aussi étiqueter les nœuds par une séquence d’identificateurs Construction d’un DAG : Idée générale : - on examine chaque instruction du bloc

- Quand on rencontre une instruction de la forme x := y +z, on cherche les nœuds qui représentent les valeurs courantes de y et z. ces nœuds peuvent être des feuilles ou des nœuds internes du DAG ; on crée un nœud étiqueté + et on lui donne deux fils : nœud correspond à y et celui de z. puis on étiquette ce nœud x. cependant s’il existe déjà un nœud dénotant le même valeur y + z ; on ajoute à ce nœud existant l’étiquette supplémentaire x :

- Si x est déjà l’étiquette d’un autre nœud , on supprime cette étiquette

- On ne crée pas de nœud pour une affectation x := y , on ajoute x à la liste des noms du nœud correspondant à y.

Algorithme :

-Nœud ( id) : une fonction qui retourne le nœud le plus récemment créé associé à l’identificateur. En pratique , l’entrée de id dans la table des symboles indique la valeur de nœud (id), initialement nœud(id) est indéfini.

-supposons que l’instruction à trois adresses courante soit(i) x := y op z, ( ii) x := op y , (iii) x := y, nous référencerons ces cas par (i) ,(ii) , (iii), nous considérons qu’un opérateur relationnel de la forme si i<= 20 aller à correspond au cas ( i), avec x indéfini.

Le processus de construction de DAG consiste à effectuer les étapes (1)-(3) pour chaque instruction du bloc à tour de rôle.

1- Si Nœud(y) est indéfini créer une feuille étiquetée y et appeler Nœud (y) ce nœud. dans le cas (i) , si Nœud(z) est indéfini , appliquer le même traitement à z.

2- Dans le cas (i) déterminer s’il existe un nœud étiqueté op dont le fils gauche est Nœud(y) et dont le fils droit est Nœud(z). si ce n’est pas le cas , créer un tel nœud .dans l’un ou l’autre cas , noter n le nœud trouvé ou créé. Dans le cas (ii) , déterminer s’il ya un nœud étiqueté op dont le seul fils est Nœud(y). sinon , créer un tel nœud . noter n le nœud ainsi trouvé ou créé. Dans le cas (iii) , n est Nœud(y).

3- Supprimer x de la liste des identificateurs attachés à Nœud (x). ajouter x à la liste des identificateurs attachés au nœud n trouvé en (2) et donner à nœud(x) la valeur n.

Exemple : Voici le code à trois adresses correspond à un bloc B :

1) t1:= 4 *i 2) t2:= a[t1]

3) t3 := 4*i 4) t4 := b[ t3]

5) t5 :=t2 * t4 6) t6:= p + t5 7) p := t6 8) t7 := i+ 1 9) i := t7

10) si i<= 20 aller à (2)

(5)

Page

L’instruction de branchement conditionnel ‘’ si ( a relop b) aller à l’’est représentée par le graphe :

Application des DAG : plusieurs sortes d’informations utiles peuvent être déduites de l’exécution de l’algorithme précédent :

- Déterminer Les sous expressions communes

- Déterminer les identificateurs dont la valeur est utilisée avant d’être définie : de l’étape1 .

- Déterminer les instructions qui calculent des valeurs qui sont utilisées à l’extérieur du bloc.

Exemple : dans le DAG précédent :

-P et i sont utilisés avant d’être évalués . ( sont évalués à l’extérieur du bloc).

- les valeurs de tous les nœuds internes peuvent être utilisées à l’extérieur du bloc.

-le résultat de la conversion du DAG en code intermédiaire ne fait apparaitre qu’une seule occurrence des expressions identiques :Reconstruisons un bloc de base à partir du DAG , en ordonnant les nœuds dans l’ordre selon lequel ils ont été créés :

T1, t2, t4, t5,t6,t7, (1) remarquer que les instructions 3 et 7 du bloc d’origine n’ont pas créé de nouveaux nœuds

Nous supposons qu’aucun des temporaires ti n’est utilisé à l’extérieur du bloc :

1) t1:= 4 *i : on a le choix entre deux identificateurs t1 et t3 , choisissons de conserver la valeur 4 *i dans t1

2) t2:= a[t1]

3) t4 := b[ t1] : cette instruction utilise t1 comme argument plutôt que t3 4) t5 :=t2 * t4

5) p:= p + t5 : nous choisissons p, puisqu’ il est probable que p et pas t6 sera utilisé à l’extérieur du bloc

6) i := i+ 1 : de façon analogue nous choisissons i plutôt que t7 pour contenir la valeur de i +1 7) si i<= 20 aller à (2)

Remarquer que les 10 instructions ont été réduites à 7.

(6)

Page 83

3. Elimination des sous expressions communes globales :

Pour faire ça de manière générale, il nous faut parcourir le graphe de flot de contrôle et récolter les informations suivantes

- les expressions produites : x op y est produite par un bloc si elle est évaluée dans le bloc et si ni x ni y ne sont redéfinis ensuite dans ce bloc

- les expressions supprimées :x op y est supprimée par un bloc B si x ou y est redéfini dans le bloc sans que l’expression soit recalculée après à l’intérieur du bloc.

- les expressions disponibles : x op y est disponible en un point p du programme si tous les chemins depuis le début du programme jusqu’a p l’évalue et si après la dernière de ces évaluations sur chacun de ces chemins, il n y a pas de nouvelle affectation de x ou y.

Algorithme de calcul de Prod[ B] :expressions produites par le bloc B -parcourir le bloc instruction par instruction

1- au départ Prod[ B]= Ø

2- à chaque instruction du type x=y op z 2-2 ajouter l’expression y op z à Prod[ B]

2-3 enlever de Prod[ B] toute expression contenant x

Algorithme de calcul de Supp[B] : expressions supprimées par le bloc B Soit U l ensemble de toutes les expressions du programme

- au départ Supp[B] =Ø

- pour chaque instruction du bloc du type x=y op z, mettre dans Supp[B] toutes les expressions de U qui contiennent x à condition qu’elle ne soit pas recalculée plus loin dans le bloc

(7)

Page

(8)

Page 85

Sur l’exemple les expressions à étudier sont e1, e2, e3 et e5 On obtient le graphe suivant :

- e 1 apparait dans l’instruction 13 du bloc B4

Est- elle disponible ? e1 ϵIn(B4) oui la dernière évaluation c ‘est

l’instruction (1) qui devient donc 1) t3 :=m-1

1’) t1 :=t3

et l’instruction (13) devient t1 :=t3 - e 2 apparait dans l’instruction 12 du bloc B3

Est- elle disponible ? e2 ϵIn(B3) oui la dernière évaluation c ‘est

l’instruction (2) qui devient donc 2)t4 :=m+n

2’) t2 :=t4

et l’instruction (12) devient c :=t4 - e 3 apparait dans l’instruction 9 du bloc B2 et l’instruction 15 du B4

- 9 de B2

Est- elle disponible ? e 3 ϵIn(B4) non Donc on ne peut pas l’éliminer.

-15 de B4

la dernière évaluation c ‘est l’instruction (9) qui devient donc

9)t5:=m-1 9’) d :=t5

et l’instruction (15) devient c :=t5 - e5 apparait dans (6) de B2,(11) de B3 et (14) de B4

- (6) de B2

Est- elle disponible ? e 5 ϵIn(B2) non Après l’élimination des sous expressions communes -11 de B3

Est- elle disponible ? e 5 ϵIn(B3) oui

la dernière évaluation c ‘est l’instruction (6) qui devient donc

(9)

Page Est- elle disponible ? e 5 ϵIn(B4) oui

la dernière évaluation c ‘est l’instruction (6) qui devient donc 6)t7:=2*c 6’’) t6 :=t7 et l’instruction (14) devient b :=t7.

4.Propagation des copies :

L’algorithme précédent, ainsi que plusieurs autres algorithmes comme l’élimination des variables d’induction introduisant des instructions de copie de la forme x :=y . des copies peuvent aussi être produites directement par le générateur de code intermédiaire, bien que la plupart la plupart d’entre elles mettent en jeu des variables temporaires locales à un bloc et peuvent donc être supprimées par la construction de DAG .

Il est quelque fois possible d’éliminer l’instruction de copie : x :=y si on détermine tous les points où x est utilisée, on peut alors remplacer x par y en tous ces pointes à condition que les propriétés suivantes soient vérifiées par chacune des utilisations u de x.

1. l’instruction i doit être la seule définition de x qui atteigne u, c.à.d que la chaine UD associée à l’utilisation u ne doit comprendre que i.

2. sur chaque chemin depuis i jusqu’à u, y compris les chemins qui traversent u plusieurs fois ( mais ne traversent pas i une seconde fois), il n’y a aucune affectation à y.

On peut définir un nouveau problème d’analyse de flot de données :

On dit que l’instruction de copie i : x := y est produite dans le bloc B si i apparait dans B et s’il n ya aucune affectation à y à l’intérieur de B.

On dit que i : x :=y est supprimée dans B si x ou y sont définies et si i n’appartient pas à B . - IN[B] est l’ensemble des copies i : x := y telles que chaque chemin depuis le nœud initial jusqu’au début de B contiennent l’instruction i et qu’il n’y a aucune affectation à y postérieurement à la dernière occurrence de i : IN[B] ne peut contenir qu’une seule instruction de copie avec x en partie gauche.

Soit U l’ensemble de toutes les instructions de copie du programme. Soulignons que des instructions x :=y distinctes sont distinctes dans U.

- On définit C-Prod[B] comme l’ensemble de toutes les copies produites dans le bloc B.

- C-Supp[B] comme l’ensemble des copies de U qui sont supprimées dans B.

Ex[B]= C-Prod[B] U ( IN|B] – C-Supp[B]) In[B] = ∩ Ex [P] / PϵP(B) et B non initial

(10)

Page 87 L’application de la procédure sur le graphe précédent nous fournit le résultat suivant:

U={d2, d4, d6, d9, d10, d14 , d15 , d16, d17, d18, d19, d20}

Bloc C-Prod[ B] C-Supp[ B]

B1 d2,d4, d6 d15 , d17,d18

B2 d9,d10, d14 d19,d16,d18, d2, d4,d20

B3 d15 ,d16,d17 d6,d14,d20

B4 d18,d19,d20 d9,d10,d17

Bloc IN[ B] OUT[ B]

B1 Ø d2,d4, d6

B2 D6,d9,d10, d14,d15 , d17

B3 d2, d4, d9, d10 ,d15,d16,d17,d18, d19

B4 d4, d6, d9,d14 ,d15,d16 ,d18, d19 , d20

Bloc IN[ B] OUT[ B]

B1 Ø d2,d4, d6

B2 d2,d4 d9,d10, d14

B3 d9,d10, d14 d9, d10 ,d15,d16,d17

B4 d9,d10, d14 D9,d14 , d18, d19 , d20

Bloc IN[ B] OUT[ B]

B1 Ø d2,d4, d6

(11)

Page

B4 d9,d10, d14 D9,d14 , d18, d19 , d20

Algorithme de propagation des copies :

Données :un graphe de flot G comportant C-In [B] qui représente la solution aux équations (1) , c.à.d l’ensemble des copies x := y qui atteignent le bloc B en suivant un chemin quelconque , sans

affectation à x ni à y postérieurement à la dernière occurrence de x := y sur ce chemin . On a également besoin des chaines DU pour donner les utilisations de chaque définition.

Résultat : un graphe de flot modifié.

Méthode : pour chaque copie i : x := y :

1. déterminer les utilisations de x qui sont atteintes par cette définition de x, à savoir i : x :=y.

2.déterminer si, pour chaque utilisation de x trouvée en (1), i appartient à C-In[B], où B est le bloc contenant cette utilisation particulière , et , en outre , si aucune définition de x ou y n’intervient avant cette utilisation de x dans B. rappelons que si i ϵ C-In[B], alors i est la seule définition de x qui atteigne B.

3. si i remplit les conditions du point(2), alors supprimer i et remplacer toutes les utilisations de x trouvées en (1 ) par y .

L’application de l’algorithme sur le graphe précédent nous fournit le résultat suivant.

1-d2 : t1 :=t3 les utilisations de t1 qui sont atteinte par d2={d11} d11ϵ C –in[B2] on ne peut pas l’éliminer , la même chose pour : d4 et d6

2-d9 : t6 := t7 les utilisations de t6={d10 ,d 16} d10 ϵ C –in[B2] , d16ϵ C –in[B3] d9 remplit les conditions alors on peut l’éliminer ,et remplacer les utilisations de t6 par t7

3-d10 : b := t7 les utilisations de b={ } d10 remplit les conditions alors on peut l’éliminer . 4-D14 :d := t5 les utilisations de d={ } d14 remplit les conditions alors on peut l’éliminer . 5-d15 : a := u2 les utilisations de a={ d13} d13 ϵ C –in[B2]

5.Analyse Globale de Flot de Données :

Pour effectuer l’optimisation de code, un compilateur doit rassembler des informations sur le programme dans son ensemble et communiquer ces informations à chaque bloc du graphe de flot.

Plusieurs fois , lors de la discussion sur les opérations d’optimisation, nous avons éprouvé le besoin de savoir si dans la suite d’un bloc fondamental , une certaine variable vivait ou pas . et pour pouvoir montrer le fonctionnement de ces opérations, nous avons fait des suppositions. La présente section va pouvoir répondre à la question sur la vivacité de la variable. Commençons par donner des définitions avant la consistance de cette analyse

Points et chemins : a l’intérieur d’un bloc de base , nous parlerons du point entre deux instructions contiguës. Un chemin de p1 à pn est une suite de points p1 pn telle que pou toute i compris 1 et n-1 :

1- soit pi est le point qui précède immédiatement une instruction et pi+1 est le point qui suit immédiatement cette instruction dans le même bloc.

2- Soit pi est la fin d’un bloc et pi+1 est le début d’un bloc successeur.

Définitions visibles :Une définition d’une variable a est une instruction de lecture ou une instruction d’assignation d’une expression à a. exemple read(a) , a := b+ 3

Une utilisation d’une variable a est une instruction dans laquelle a apparait comme un opérande : exemple : d := e-a

Une instruction peut être à la fois une définition et une utilisation de la même variable : a :=a-1

Une variable a vit à travers un fragment de code si ce dernier contient uniquement des utilisations de a.

Une variable a est supprimée au niveau de chaque définition de a.

Nous dirons qu’une définition d est visible depuis un point p s’il existe un chemin allant du point suivant immédiatement d jusqu’à p, tel que d ne soit pas supprimé le long de ce chemin.

Connaissant le point p1 d’une définition d’une variable a, nous nous intéressons à savoir à quel point p2 du code, la variable est utilisée. Si p2 n’existe pas nous pouvons conclure alors que a ne vit pas

(12)

Page 89 définition ( u-d).

Détermination des chaines U-d : il existe une chaine entre un point p1 et un point p 2 du code s’il existe dans le graphe de flow de ce code une chaine entre le bloc contenant l’instruction située au point p1 et le bloc contenant l’instruction située au point p2, nous allons manipuler les structures suivante pour un bloc B :

GEN[ B] : est l’ensemble de définitions du bloc B qui aboutissent au point situé juste après la dernière instruction de B.

On dit qu’une définition d’une variable a aboutit à un point p si les deux conditions suivantes sont satisfaites :

1) Il existe une chaine entre la définition et le point p

2) Il n’existe pas d’autres définitions de a le long de cette chaine.

KILL[B] : est l’ensemble des définitions des variables x se trouvant à l’extérieur du bloc B qui sont tuées par B c.à.d les définitions des variables x se trouvant à l’extérieur de B telles que x est définie dans B.

IN[ B] est l’ensemble des définitions du code général qui aboutissent au point situé juste avant le leader de B.

OUT[ B] est l’ensemble des définitions du code général qui aboutissent au point situé juste après la dernière instruction de B.

Exemple : il existe définitions dans le graphe :

La détermination de IN[ B] et OUT [ B] au vu du graphe de flow n’est pas évidente. Nous utiliserons la procédure suivante pour calculer IN[ B] et OUT[B] . La procédure est basée sur les équations suivantes :

IN[ B]= U OUT[P] :p étant un prédécesseur de B OUT[B]= IN[B] – KILL[ B] + GEN[ B]

Procedure

Début pour chaque bloc B faire

Debut IN[B] := 0 ; OUT[B] := GEN[ B] ; fin;

1: p:= 0 2: i:=1

3:if I<= n goto 5 (B4) 4:goto 17 (B5)

5:t1:= I *3 6: t2:= a-3 7: t3:= t2[t1]

8 :t4 := i*3 9 : t5 := b – 3 10 :t6 := t5[ t4]

11 :t7 :=t3 * t6 12 : t8 := p + t7 13 : p := t8 14 : t9 := i+ 1 15 : i := t9

16 : goto 3 B(2)

Les ensembles GEN[B] , KILL[ B] des blocs Bi pour i=1..4 du graphe précédent sont montrés dans le tableau suivant :

Bloc GEN[B] KILL[ B]

B1 d1 , d2 d11, d13

B2 - -

B3 - -

B4 d3……d13 D1,d2

(13)

Page Début Changer := faux ;

Pour chaque bloc B faire

Début nouvin:= U out[p];

Si nouvin <> IN [ B] alors changer := vrai ; IN[B] := nouvin ;

OUT[B] := IN [ B] – KILL[ B ] U GEN[B] ; fin;fin;

Fin;

L’application de la procédure sur le graphe précédent nous fournit le résultat suivant:

Bloc In Out In Out In Out

B1 d1,d2 d1,d2 d1,d2

B2 d1..d13 d1 ..d13 d1 ..d13 d1 ..d13

B3 d1 ..d13 d1 ..d13

d3 ..d13 d3 ..d13 d1 ..d13 d1 ..d13

Références

Documents relatifs

La surface lisse Planar pour les portes à rainures L, déclinée en 6 teintes Matt deluxe exclusives Hörmann, vous charmera par sa grande élégance (illustration de gauche

(b) Puisque les évènements &#34;obtenir une blanche&#34; et &#34;obtenir une noire &#34; sont incompatibles, on se ramène à la pioche ordonnée de deux boules blanches puis de

La surface créée s'appuie sur un cône défini dans l'ordre par le nom de son sommet (ou sa définition entre parenthèses) puis le nom d'un autre point de l'axe (ou sa définition

R51/53: Toxique pour les organismes aquatiques, peut entraîner des effets néfastes à long terme pour l´environnement aquatique R65: Nocif: peut provoquer une atteinte des poumons

[r]

d) Tracez à main levée le graphique de la fonction.. Du haut d’une falaise, à 120 m au-dessus du niveau de la mer, un appareil lance dans les airs un pigeon d’argile. b) Le

[r]

[r]