Parmi les difficultés rencontrées au niveau des méthodes de
compilation classiques, on retrouve assez souvent le problème du
sur-coût introduit par le code de
contrôle [5,8]. En effet, des techniques comme la
génération "automatique" de code, font fréquemment appel à des
énumérations (espace d'itération de polyèdres) pour lesquelles la
majorité du temps de calcul sera passée dans divers branchements
conditionnels (imbrications de boucles et de tests). Un travail est
donc nécessaire à la fois pour diminuer au maximum le temps de calcul
d'une itération, et pour stopper au plus tôt tout parcours
inutile (corps de la boucle vide ou exécuté une fois sur N).
On trouve dans la littérature de nombreux algorithmes visant à optimiser le code à l'aide de techniques désormais bien connues (et présentes dans la plupart des compilateurs) : sous-expressions communes, propagation des copies, élimination de code mort, déplacement de code, etc. [1,2,14,15]. Tous ces travaux ont permis une importante amélioration des performances des programmes. Malheureusement, ces algorithmes interviennent "trop tard" dans le processus de compilation, et le compilateur ne peut bien souvent effectuer les transformations, faute d'une meilleure connaissance de la structure du code. En effet, la représentation sous forme de code "3 adresses" utilisée par le compilateur ne permet pas de profiter de propriétés opératoires telles que l'associativité, ou la distributivité.
Notre démarche consiste donc à tenter d'appliquer de telles méthodes, dans un phase préliminaire, en nous appuyant sur une vision plus "globale" de la structure du code à optimiser. Nos objectifs sont multiples : reconnaître les tests cachés, placer au plus tôt les branchements conditionnels, extraire les calculs invariants, etc.