Commit a1ace968 authored by Patrick Baudin's avatar Patrick Baudin

[doc] restore PDG and Slicing french documentation

parent 1d061de1
biblio.bib
frama-c-book.cls
frama-c-cover.pdf
frama-c-left.pdf
frama-c-right.pdf
main.pdf
.PHONY: all clean
all: main.pdf
GENERATED=biblio.bib
GENERATED+=frama-c-book.cls frama-c-cover.pdf frama-c-left.pdf frama-c-right.pdf
include ../MakeLaTeXModern
DWNLDDIR=../manuals
DOCNAME=pdg-documentation-fr.pdf
TEST_DIR=../../tests/pdg/
BIB_FILE = ../slicing/bib-slicing.bib
main.bbl : $(BIB_FILE)
@echo "=== Fichier .bib plus récent -> effacement du .bbl"
rm -f $(SRC).bbl
main.pdf: $(FRAMAC_MODERN) $(BIB_FILE) \
main.tex pdg.tex macros_pdg.tex \
intro.tex conclusion.tex \
data.tex ctrl.tex calls.tex utilisation.tex mark.tex impact.tex \
../images/cealistlogo.jpg \
exple-call.c call-f.pdf call-g.pdf \
ctrl-dpds.pdf ex-goto.pdf goto.pdf pdg-call.pdf
###############################################################################
GENERATED+=call-f.fig call-g.fig
%.fig : %.dot
dot -Tfig $< > $@
GENERATED+=call-f.pdf call-g.pdf
%.pdf : %.fig
fig2dev -L pdf $< $@
GENERATED+=call-f.dot call-g.dot
call-%.dot : $(TEST_DIR)/call.%.dot
cp $< $@
call-%.dot :
@echo
@echo "ERROR : $@ not found : you should run PDG tests to have it"
@echo " Run : cd ../.. ; make pdg_tests ; cd - "
@echo
exit 1
GENERATED+=exple-call.c
exple-%.c : $(TEST_DIR)/%.c
sed "1,/BDOC/d" $< > $@
###############################################################################
%.pdf: %.tex
pdflatex $*
bibtex $*
pdflatex $*
pdflatex $*
install: main.pdf
@echo "copying main.pdf in $(DWNLDDIR)/$(DOCNAME)"
@rm -f "$(DWNLDDIR)/$(DOCNAME)"
@cp main.pdf "$(DWNLDDIR)/$(DOCNAME)"
clean:
rm -rf *~ *.aux *.log *.nav *.out *.snm *.toc *.lof *.pp *.bnf \
*.haux *.hbbl *.htoc \
*.cb *.cb2 *.cm? *.bbl *.blg *.idx *.ind *.ilg \
$(GENERATED)
###############################################################################
\chapter{Dépendances interprocédurales}\label{sec-intro-call}
On a vu qu'un PDG est associé à une fonction.
La question se pose donc de savoir
comment calculer des dépendances interprocédurales, c'est-à-dire comment mettre
en relation les appels de fonctions et les dépendances des fonctions appelées.
Nous allons tout d'abord voir qu'un appel de fonction
est représenté par plusieurs éléments dans le PDG (\S\ref{sec-call}).
Puis, nous allons voir que pour mettre en relation des appels et les fonctions
appelées, ils faut ajouter d'autres éléments à chaque fonction
(\S\ref{sec-fct-inout}).
\section{Appels de fonction}\label{sec-call}
L'instruction contenant l'appel est représentée par plusieurs
éléments dans le graphe de dépendances
afin de pouvoir plus précisément mettre en relation les appels aux
fonctions appelées.
Les éléments créés sont les suivants~:
\begin{itemize}
\item un élément pour chaque paramètre de la fonction appelée;
les dépendances sont crées par une simulation
de l'affectation des arguments d'appel dans les paramètres formels,
\item un élément représentant le contrôle du point d'entrée de la fonction
appelée (un peu comme si l'appel était dans un bloc et que ce noeud
représentait ce bloc),
\item un élément pour chaque sortie, dépendant des entrées correspondantes.
\end{itemize}
Pour ne pas avoir à calculer les flots de données de toutes les fonctions de
l'application, il a été décidé d'utiliser les dépendances ({\it from})
calculées indépendamment par \ppc.
La liste des entrées et des sorties, ainsi que les dépendances entre les unes et
les autres sont extraites des spécifications des fonctions appelées, et non de
leur PDG\footnote{c'est peut-être un problème
si on fait de la coupure de branche, car les dépendances peuvent être réduites
par une telle spécialisation.}.
Ceci est vrai également pour les
fonctions dont le code est absent de l'application étudiée
car cela permet d'être cohérent avec les autres analyses.
Cela permettra en particulier, d'utiliser d'éventuelles propriétés
fournies par la suite par l'utilisateur.
\begin{exemple}
\begin{tabular}{m{0.35\textwidth} m{0.6\textwidth}}
\begin{verbatim}
struct {int a;
int b; } G;
/*@ assigns \result {a},
G.a {G, a} */
int g (int a);
int f (int x, int y) {
G.b = x;
x = g (x+y);
return x + G.b;
}
\end{verbatim}
&
Ici, pour représenter l'appel à \verbtt{g} dans \verbtt{f} dans le PDG,
on va avoir~:
\begin{itemize}
\item un élément représentant le point d'entrée dans \verbtt{g},
\item un élément $e_1$ pour représenter \verbtt{a = x+y},
c'est-à-dire l'affectation de l'argument de l'appel
dans le paramètre formel de \verbtt{g},
\item un élément $e_2$ pour calculer la valeur de retour de \verbtt{g},
qui dépend de la valeur de $e_1$
(utilisation de la spécification de $g$),
\item et enfin, un élément $e_3$ qui représente la seconde sortie de \verbtt{g}~:
\verbtt{G.a} qui dépend du paramètre \verbtt{a} et donc de $e_1$
et de des éléments $\{ e_G \}$
correspondant à
la valeur de $G$ avant l'appel
(selon la spécification de $g$).
\end{itemize}
\end{tabular}
\end{exemple}
On note que, contrairement à ce qui était fait dans la version précédente,
on ne crée par d'élément pour l'entrée implicite $G$ de $g$ dans $f$.
Cela permet d'améliorer la précision des dépendances lorsque
l'ajout d'un tel noeud conduisait au regroupement de plusieurs données.
Ainsi, dans l'exemple précédent, on ne crée pas d'élément pour
représenter la valeur de $G$ avant l'appel, même si l'élément $e_3$ en dépend,
et on conserve donc l'information que $G.b$ ne dépend que de l'affectation
précédent l'appel.
\section{Entrées/sorties d'une fonction}\label{sec-fct-inout}
Pour relier un appel de fonction au PDG de la fonction appelée,
il faut ajouter des éléments représentant ses entrées/sorties,
c'est-à-dire~:
\begin{itemize}
\item un élément correspondant au point de contrôle d'entrée
dans la fonction,
\item deux éléments pour chaque paramètre (cf. \S\ref{sec-decl-param}),
\item un élément pour les entrées implicites (cf. \S\ref{sec-impl-in}),
\item un élément pour la sortie de la fonction si celle-ci retourne
quelque chose.
\end{itemize}
On note que, contrairement à ce qui était fait dans la version précédente,
on ne crée par d'élément pour les sorties implicites de la fonction.
Cela permet d'améliorer la précision des dépendances lorsque
l'ajout d'un tel noeud conduisait au regroupement de plusieurs données.
C'est par exemple le cas lorsqu'une fonction calcule $G.a$,
puis $G.a.x$ car un élément de sortie regrouperait les deux alors que
si par la suite on s'intéresse juste à $G.a.x$ à la sortie de la fonction,
le fait de ne pas avoir créé cet élément permet de retrouver l'information plus
précise.
\subsection{Entrées implicites}\label{sec-impl-in}
Au cours du calcul du PDG, on mémorise l'utilisation des données
qui ne sont pas préalablement définies.
Cela permet par la suite que créer des éléments pour ces entrées dites
implicites. On ne crée pas d'élément pour les variables locales non
initialisées, mais un message d'avertissement est émis.
Il est possible que ce soit une fausse alerte dans le cas où l'initialisation
est faite dans une branche dont la condition est forcement vrai à chaque
exécution où l'on passe par la suite par l'utilisation.
Diverses stratégies de regroupement de ces entrées peuvent être utilisées.
A ce jour, l'outil construit tous les éléments lui permettant d'avoir une
meilleure précision. C'est-à-dire que deux éléments peuvent représenter les
données qui ont une intersection.
\subsection{Déclaration des paramètres formels}\label{sec-decl-param}
En plus de l'élément représentant la valeur des paramètres,
on crée un second élément qui représente sa déclaration,
le premier dépendant du second.
Cette représentation peut permettre d'avoir une meilleure précision
dans le cas où certains calcul ne dépendent pas de la valeur du
paramètre, mais uniquement de sa déclaration.
\begin{exemple}
\begin{tabular}{m{5cm} m{\linewidth - 6cm}}
\begin{verbatim}
int g (int a) {
G = 2 * a;
a = calcul_a ();
return a;
}
int f (void) {
int x = calcul_x ();
return g (x);
}
\end{verbatim}
&
On voit que la valeur de retour de \verbtt{g} ne nécessite pas la valeur initiale
de \verbtt{a}, mais seulement sa déclaration. La valeur de retour de \verbtt{f}
ne dépend donc pas de l'appel à \verbtt{calcul\_x}.
\end{tabular}
\end{exemple}
Ce point n'est pas encore implémenté dans la version actuelle,
car dans des cas plus complexe, il est délicat de savoir ce qu'il faut
garder dans la fonction appelante. Le plus simple serait sans doute
de transformer le paramètre formel en une variable locale,
mais le filtrage permet à l'heure actuelle de garder ou d'effacer des
éléments existants, mais pas d'effectuer des transformations de code...
\section{Fonctions à nombre d'arguments variable}
Pour l'instant, on ne calcule pas le PDG des fonctions à nombre
d'arguments variable, c'est-à-dire que pour le reste de l'application,
tout se passe comme si on n'avait pas le code source de ces fonctions.\\
En revanche, les appels à de telles fonctions sont gérées de manière semblable à
ce qui est fait pour les autres appels, c'est-à-dire~:
\begin{itemize}
\item création d'un noeud d'entrée pour chaque argument d'appel,
(il y en a donc éventuellement plus que que paramètres formels dans le
déclaration de la fonction appelée)
\item utilisation des informations {\it from} pour créer les éventuelles
entrées implicites, les sorties, et les liens de dépendance.
\end{itemize}
\section{Exemple}
\begin{exemple}
\lstinputlisting[language=c]{exple-call.c}
\end{exemple}
Graphe de la fonction \verbtt{f}: \\
\includegraphics[width=0.6\textwidth]{call-f}
\\
\clearpage
Graphe de la fonction \verbtt{g}: \\
\includegraphics[width=1\textwidth]{call-g}
\\
Les graphes sont ceux qui sont effectivement produits par l'outil.
\chapter{Conclusion}
La version actuelle de ce greffon semble fonctionner.
Elle est utilisée par les greffons {\sc Security}, {\sc Sparecode} et
{\sc Slicing}. Ces résultats peuvent également être visualisés
graphiquement en utilisant la fonction d'exportation
au format {\tt .dot}.\\
D'autres information relatives au développement peuvent être trouvées dans la documentation du code dont un point d'entrée
est~:
\centerline{\tt doc/code/pdg/index.html}
\section{Limitations}
Les fonctions ayant un nombre d'arguments variable
ne sont pas traitées (mais les appels à de telles fonctions sont gérés).
Par ailleurs, les calculs se basant sur l'analyse de valeur,
et sur le calcul des dépendances fonctionnelles (\from)
il hérite des limitations de ces modules.
#FIG 3.2
Portrait
Center
Metric
A4
100.00
Single
-2
1200 2
0 32 #ffffff
6 4410 2610 5355 3195
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
4417 2645 5314 2645 5314 3165 4417 3165 4417 2645
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
4417 2645 5314 2645 5314 3165 4417 3165 4417 2645
4 1 0 0 0 16 17 0.0000 6 180 810 4866 2976 START\001
-6
6 5715 6210 6120 6795
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
5728 6236 6082 6236 6082 6755 5728 6755 5728 6236
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
5728 6236 6082 6236 6082 6755 5728 6755 5728 6236
4 1 0 0 0 16 17 0.0000 6 180 165 5905 6566 B\001
-6
6 7470 4860 7965 5445
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
7488 4889 7960 4889 7960 5409 7488 5409 7488 4889
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
7488 4889 7960 4889 7960 5409 7488 5409 7488 4889
4 1 0 0 0 16 17 0.0000 6 180 300 7724 5220 S2\001
-6
6 5715 4860 6120 5445
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
5740 4889 6094 4889 6094 5409 5740 5409 5740 4889
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
5740 4889 6094 4889 6094 5409 5740 5409 5740 4889
4 1 0 0 0 16 17 0.0000 6 180 150 5917 5220 Z\001
-6
6 4725 5715 5220 6255
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
4748 5716 5220 5716 5220 6236 4748 6236 4748 5716
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
4748 5716 5220 5716 5220 6236 4748 6236 4748 5716
4 1 0 0 0 16 17 0.0000 6 180 285 4984 6047 Z1\001
-6
6 6435 5715 6975 6255
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
6472 5716 6968 5716 6968 6236 6472 6236 6472 5716
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
6472 5716 6968 5716 6968 6236 6472 6236 6472 5716
4 1 0 0 0 16 17 0.0000 6 180 285 6720 6047 Z2\001
-6
6 4455 7155 5220 7740
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
4464 7181 5196 7181 5196 7700 4464 7700 4464 7181
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
4464 7181 5196 7181 5196 7700 4464 7700 4464 7181
4 1 0 0 0 16 17 0.0000 6 180 675 4830 7511 STOP\001
-6
6 6480 3375 6885 3960
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
6519 3401 6874 3401 6874 3921 6519 3921 6519 3401
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
6519 3401 6874 3401 6874 3921 6519 3921 6519 3401
4 1 0 0 0 16 17 0.0000 6 180 165 6696 3732 A\001
-6
6 4725 4185 5220 4725
2 3 0 1 32 32 0 -1 20 0.000 0 0 0 0 0 5
4745 4204 5194 4204 5194 4724 4745 4724 4745 4204
2 3 0 1 0 0 0 0 -1 0.000 0 0 0 0 0 5
4745 4204 5194 4204 5194 4724 4745 4724 4745 4204
4 1 0 0 0 16 17 0.0000 6 180 300 4970 4535 S1\001
-6
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
5310 2925 6345 2925 6705 3420
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
4500 3150 4275 5445 4680 7200
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
6525 3600 5175 3600 4950 4185
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
6885 3600 7245 3600 7650 4905
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
5175 4455 5625 4455 5895 4905
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
5760 5175 5310 5175 4950 5715
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
6075 5175 6480 5175 6750 5715
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
4950 6210 4995 6390 5715 6615
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
6750 6210 6705 6390 6075 6615
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
7650 5400 7650 6300 5175 7425
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
2 1 1.00 60.00 120.00
5850 6750 5850 6975 5175 7290
\newcommand{\text}[1]{\mbox{#1}}
\newcommand{\impl}{\Rightarrow}
\newcommand{\et}{\wedge}
\newcommand{\ou}{\vee}
\newcommand{\define}{\Leftrightarrow{def}}
\newcommand{\mssi}{\Leftrightarrow}
\newcommand{\llb}{\llbracket}
\newcommand{\ch}[1]{[#1]}
\newcommand{\mch}[1]{[#1[}
\newcommand{\allch}[1]{\llb #1] }
\newcommand{\allmch}[1]{\llb #1[}
\newcommand{\n}[1]{\ensuremath{\mathfrak{#1}}}
\newcommand{\nE}{\n{E}}
\renewcommand{\P}[1]{\ensuremath{\mathit{P}(\n{#1})}}
\newcommand{\D}[2]{\ensuremath{\mathit{D}(\n{#1},\n{#2})}}
\newcommand{\Pd}[1]{\ensuremath{\mathit{Pd}(\n{#1})}}
\newcommand{\Pdi}[1]{\ensuremath{\mathit{Pd}^{\infty}(\n{#1})}}
\newcommand{\Pda}[1]{\ensuremath{\mathit{Pd}^{+}(\n{#1})}}
\newcommand{\dpdc}[1]{\ensuremath{\mathit{DpdC}(\n{#1})}}
\newcommand{\codpdc}[1]{\ensuremath{\mathit{CoDpdC}(\n{#1})}}
\renewcommand{\succ}[1]{\ensuremath{\mathit{Succ}(\n{#1})}}
\newcommand{\succl}[1]{\ensuremath{\mathit{Succ_{L}}(\n{#1})}}
\newcommand{\ssi}{si et seulement si }
\chapter{Dépendances de contrôle}\label{sec-cdg}
\section{Introduction}
Intuitivement, un noeud \n{n} du PDG a une dépendance de contrôle sur un noeud
\n{c}
si le fait d'exécuter \n{n} dépend du résultat de l'exécution de \n{c}.
Typiquement, \n{c} est un noeud qui a plusieurs successeurs, comme un {\sc if} par
exemple,
et en fonction de la branche qui est choisie, \n{n} est exécuté ou non.
Nous allons voir qu'il existe de nombreuses façons de calculer ces
dépendances de contrôle, mais que nous avons du les adapter car
elle ne correspondent pas exactement à ce que l'on souhaitait faire.
Le principal problème est que
nous nous proposons d'analyser correctement
toute fonction, même en présence de sauts quelconques, voire de boucles
infinies; ce qui, comme nous allons le voir,
pose des problèmes particuliers au niveau des dépendances de contrôle.
\section{Etat de l'art}
Commençons tout d'abord par rappeler quelques définitions
et rapporter les résultats que l'on trouve dans la littérature.
\subsection{CFG}
Le \indexdef{graphe de flot de contrôle} est un graphe orienté qui définit l'ordre
d'exécution des instructions. Un noeud \n{a} est connecté à un noeud \n{b}
si l'instruction \n{b} peut suivre immédiatement
l'instruction \n{a} dans une trace l'exécution.
On dit que \n{b} est un \indexdef{successeur} de \n{a}.
On représente l'ensemble des successeurs d'un noeud \n{a} par $\succ{a}$.
On dit aussi que \n{a} est un \indexdef{prédécesseur} de \n{b}.\\
Un noeud est considéré comme une entrée dans le CFG s'il n'a pas de prédécesseur.
Il est généralement considéré qu'il y a un unique noeud d'entrée,
et que tous les noeuds du CFG sont atteignables depuis ce point d'entrée.
Cette hypothèse semble raisonnable car on s'intéresse au CFG d'une fonction
qui a bien un seul point d'entrée, et les instructions non atteignables depuis
le point d'entrée sont du
code mort que l'on peut donc ignorer dans les analyses.\\
Un noeud est considéré comme une sortie du CFG s'il n'a pas de successeur.
Son unicité et son accessibilité sont discutées plus loin.
\subsection{Postdominateurs}
La plupart des algorithmes de calcul des dépendances de contrôle
se basent
sur un CFG dans lequel sont ajoutés deux noeuds spéciaux {\sc start} et
{\sc stop} (on notera \nE{} ce dernier),
et sur la notion de \indexdef{postdominateur} dont une définition est
la suivante~:
\begin{definition}{postdominateur}
Une instruction \n{a} est {\bf postdominée} par une instruction \n{b}
(\n{b} est un {\bf postdominateur} de \n{a})
si tous les chemins qui vont de \n{a} au noeud \nE{} contiennent \n{b}.
\end{definition}
En d'autres termes, si on passe par l'instruction \n{a},
on passe forcement par tous ses postdominateurs avant de sortir.
Ou encore,
toutes les traces partant de \n{a} et allant à \nE{} passent par \n{b}.\\
Certains auteurs définissent également
le \indextxtdef{premier postdominateur}{postdominateur!premier}
(appelé aussi \indextxtdef{postdominateur immédiat}{postdominateur!immédiat})
de la façon suivante~:
\begin{definition}{premier postdominateur}
\n{b} est le premier postdominateur de \n{a} \ssi~:
\begin{itemize}
\item \n{b} postdomine \n{a},
\item et \n{b} est postdominé par tous les autres postdominateurs de \n{a}.
\end{itemize}
\n{b} est donc unique.
\end{definition}
Cela permet de construire un arbre (appelé PDT pour {\it Post-Dominator Tree})
représentant cette relation dans lequel les noeuds sont les mêmes que
ceux du CFG et le père de chaque noeud est son premier postdominateur.\\
L'ensemble des postdominateurs d'un noeud \n{a} est donné par~:
$$
\Pd{a} = \{a\} \bigcup \bigcap_{s \in \succ{a}} \Pd{s}
$$
qui traduit le fait que \n{b} postdomine \n{a} \ssi $\n{b} = \n{a}$
ou \n{b} postdomine tous les successeurs de \n{a}.
La méthode de calcul consiste à initialiser tous les ensembles à $\top$,
et à itérer jusqu'à stabilisation.
La fonction étant décroissante, la convergence est assurée.\\
La notion classique de postdominateurs suppose que le CFG ait un point unique de
sortie \nE,
et que celui-ci soit atteignable depuis tous les autres points du graphe.
Si ce n'est pas le cas, à la fin de ce calcul,
pour les \n{a} n'ayant pas de chemin vers \nE, on a~: $\Pd{a} = \top$.\\
\subsection{Dépendances de contrôle}
Intuitivement, on dit qu'une instruction \n{a} a une \indextxtdef{dépendance de
contrôle}{dépendance!contrôle} sur une instruction \n{c}
si, en fonction du choix que l'on fait en \n{c}, on passe ou non en \n{a}.
Cela suppose donc qu'il y ait un choix à faire en \n{c},
c'est-à-dire que le noeud correspondant dans le CFG
ait plusieurs successeurs.\\
Les dépendances de contrôle sont définies par \cite{Ferrante87}
de la façon suivante~:
\begin{definition}{dépendances de contrôle selon \cite{Ferrante87}}
Pour deux noeuds \n{a} et \n{b} du CFG, \n{b} dépend de \n{a} ssi~:
\begin{itemize}
\item il existe un chemin P de \n{a} a \n{b}
tel que tout noeud Z de P, différent de \n{a} et de \n{b}, est postdominé
par \n{b},
\item et \n{a} n'est pas postdominé par \n{b}.
\end{itemize}
\end{definition}
Ce qui signifie que~:
\begin{itemize}
\item plusieurs chemins partent de \n{a},
\item qu'il existe un chemin qui passe par \n{b},
\item et qu'il existe aussi un chemin qui ne passe pas par \n{b}
(sinon, \n{a} serait postdominé par \n{b}).
\end{itemize}
Ce qui conduit à une autre
définition, équivalente à la précédente~:
\begin{definition}{dépendance de contrôle}
Une instruction \n{b} a une {\bf dépendance de contrôle} vis à vis de \n{a} si~:
\begin{itemize}
\item \n{b} postdomine certains successeurs de \n{a},
\item \n{b} ne postdomine pas tous les successeurs de \n{a}.
\end{itemize}
\end{definition}
Pour calculer le CDG, l'algorithme de référence est le suivant~:
\begin{algo}{calcul du CDG selon \cite{Ferrante87}}
\begin{itemize}
\item soit ACFG le CFG (+ START et {\sc stop}) dans lequel sont ajoutés~:
\begin{itemize}
\item un noeud ENTRY,
\item une arrête (ENTRY,START),
\item une arrête (ENTRY,
{\sc stop}),
\end{itemize}
\item soit S l'ensemble des arrêtes (\n{a},\n{b}) de ACFG
telles que \n{b} ne postdomine pas \n{a}, \\
(c'est-à-dire les arrêtes partant des noeuds \n{a} qui ont plusieurs successeurs)
\item soit \n{l} le plus petit ancêtre commun à \n{a} et \n{b} dans PDT\\
(on peut montrer que soit \n{l}=\n{a}, soit \n{l} est le père de \n{a} dans PDT)
\begin{itemize}
\item si \n{l} est le père de \n{a} dans PDT, tous les noeuds du PDT sur le chemin
entre \n{l} et \n{b} (\n{b} compris, mais pas \n{l}) dépendent de \n{a},
\item si \n{l} = \n{a}, tous les noeuds du PDT sur le chemin
entre \n{a} et \n{b} (\n{a} et \n{b} compris) dépendent de \n{a}.
\end{itemize}
\end{itemize}
En fait, il est plus simple de dire que tous les noeuds du PDT sur le chemin
entre \n{b} et le père de \n{a} (\n{b} compris, mais pas le père de \n{a}) dépendent de
\n{a}.
\end{algo}
La relation de dépendance étant transitive, on peut choisir de calculer
uniquement les dépendances directes ou d'inclure les dépendances indirectes.
\begin{exemple}
\begin{tabular}{m