Rapport pour le projet du Compilateur MISC

Documents pareils
MICROINFORMATIQUE NOTE D APPLICATION 1 (REV. 2011) ARITHMETIQUE EN ASSEMBLEUR ET EN C

ET 24 : Modèle de comportement d un système Boucles de programmation avec Labview.

Bases de programmation. Cours 5. Structurer les données

Représentation des Nombres

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Programmation C. Apprendre à développer des programmes simples dans le langage C

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

RACCOURCIS CLAVIERS. DEFINITION : Une «combinaison de touches» est un appui simultané sur plusieurs touches.

2.4 Représentation graphique, tableau de Karnaugh


Conventions d écriture et outils de mise au point

DU BINAIRE AU MICROPROCESSEUR - D ANGELIS CIRCUITS CONFIGURABLES NOTION DE PROGRAMMATION

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

LES OUTILS D ALIMENTATION DU REFERENTIEL DE DB-MAIN

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

1) Installation de Dev-C++ Téléchargez le fichier devcpp4990setup.exe dans un répertoire de votre PC, puis double-cliquez dessus :

Outils pour la pratique

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

ASR1 TD7 : Un microprocesseur RISC 16 bits

Réalisation de cartes vectorielles avec Word

Chap 4: Analyse syntaxique. Prof. M.D. RAHMANI Compilation SMI- S5 2013/14 1

Algorithmique et Programmation, IMA

Licence Sciences et Technologies Examen janvier 2010

PROJET ALGORITHMIQUE ET PROGRAMMATION II

STAGE IREM 0- Premiers pas en Python

Inscription de votre site sur Google Configuration du sitemap et de Webmaster Tools pour PrestaBox

Quelques éléments de compilation en C et makefiles

Les chaînes de caractères

Architecture des ordinateurs

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Les Bases. Messaoudi Khaled, Boukelal Hanane (Etudiants Informatique ) 2015.

Contrôle d accès UTIL TP N 1 découverte

IFT1215 Introduction aux systèmes informatiques

Clé USB. Quel type de données peut contenir une clé USB?

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Traduction des Langages : Le Compilateur Micro Java

Plan du cours. Historique du langage Nouveautés de Java 7

Jade. Projet Intelligence Artificielle «Devine à quoi je pense»

à l édition de textes

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

La mémoire. Un ordinateur. L'octet. Le bit

Chapitre I Notions de base et outils de travail

Les arbres binaires de recherche

Représentation d un entier en base b

Java Licence Professionnelle CISII,

Informatique Générale

Limitations of the Playstation 3 for High Performance Cluster Computing

Gestion d identités PSL Exploitation IdP Authentic

Mesurer les performances (CPU) sous Linux

Algorithmique et Programmation Fonctionnelle

IV- Comment fonctionne un ordinateur?

Tutoriel Création d une source Cydia et compilation des packages sous Linux

Saisir des règlements par le relevé de banque

Tablette Pegasus PC Notes. Code : Conrad sur INTERNET Version 02/ Conditions du système.

Déroulement. Evaluation. Préambule. Définition. Définition. Algorithmes et structures de données 28/09/2009

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

CONFIGURATION DE L AUTOMATE SIEMENS

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Rappels d architecture

Choisir le mode d envoi souhaité. Option 1 : Envoyer un SMS à un nombre réduit de numéros (0 10 )

Initiation. àl algorithmique et à la programmation. en C

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Créer et partager des fichiers

UE C avancé cours 1: introduction et révisions

L informatique en BCPST

Introduction à l algorithmique et à la programmation M1102 CM n 3

Utiliser Glary Utilities

REALISATION d'un. ORDONNANCEUR à ECHEANCES

TP Bases de données réparties

INITIATION A L INFORMATIQUE. MODULE : Initiation à l'environnement Windows XP. Table des matières :

Unix/Linux I. 1 ere année DUT. Université marne la vallée

Manuel d utilisation 26 juin Tâche à effectuer : écrire un algorithme 2

CREER ET ANIMER SON ESPACE DE TRAVAIL COLLABORATIF

Tutorial Terminal Server sous

Gestion hybride de la mémoire dynamique dans les systèmes Java temps-réel

Architecture matérielle des systèmes informatiques

Cours d Informatique

Introduction aux concepts d ez Publish

Sélection du contrôleur

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Chapitre 2. Classes et objets

Cours No 3 : Identificateurs, Fonctions, Premières Structures de contrôle.

Architecture des ordinateurs TD1 - Portes logiques et premiers circuits

Atelier Le gestionnaire de fichier

Cahier n o 7. Mon ordinateur. Gestion et Entretien de l ordinateur

Architecture de l ordinateur

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Le langage C. Séance n 4

CM2 L architecture MIPS32

Partie publique / Partie privée. Site statique site dynamique. Base de données.

SYSTÈME DE GESTION DE FICHIERS

Ateliers L A TEX L A TEX portable ou

SIP. Plan. Introduction Architecture SIP Messages SIP Exemples d établissement de session Enregistrement

CHAPITRE VIII : Les circuits avec résistances ohmiques

GUIDE D INSTALLATION RAPIDE DEXH264

EXERCICE N 9. Base Centrale de pilotage. Notions abordées : Création d objets personnels. Utilisation de fonctions numériques


Transcription:

Rapport pour le projet du Compilateur MISC Nicolas Bonvin, Gilles Diacon, Xavier Perséguers École Polytechnique Fédérale de Lausanne 2 février 2003 1 Optimisations Le code généré par le compilateur n étant pas toujours très optimal, nous avons choisi de mettre au point un certain nombre d optimisations pour étendre quelque peu les possibilités de notre compilateur. 1.1 Expressions arithmétiques La génération des expressions arithmétiques, telle que proposée, n était pas vraiment efficace. Une expression du type 3 4 était codée de façon à stocker dans deux registres chacune des constantes, avant d effectuer l opération. Nous avons modifié un peu le code pour tirer partie des instructions comportant une valeur immédiate. Nous n utilisons donc plus qu un seul registre pour une expression telle que la précédente. En outre, nous générons d abord le sous-arbre le plus profond, ceci afin de lui laisser un maximum de registres et ne pas en perdre un pour le stockage intermédiaire du second sous-arbre. Multiplication : La multiplication, qui est un opérateur coûteux, est remplacée par un décalage vers la gauche si l une des opérandes est une puissance de 2. Problèmes rencontrés : La combinaison de l utilisation des opérations immédiates et de la génération du sous-arbre le plus profond en premier amène à se retrouver avec les opérandes inversées si le sous-arbre droit est plus profond. Dans le cas des opérateurs + ou *, ce n est pas grave, mais pour les autres opérateurs, le résultat est faussé. Deux solutions étaient possibles : ne pas changer l ordre de génération si les opérandes peuvent être utilisées dans une instruction immédiate, ou garder le comportement initial dans ce cas, à savoir charger les opérandes dans des registres. C est cette deuxième solution que nous avons préférée. 1

Nous avons aussi fait attention à utiliser les instructions immédiates signées ou non-signées si elles permettaient de faire l opération escomptée. Dans le cas de constantes trop grandes, la solution standard consistant à stocker la valeur immédiate dans un registre a été retenue. 1.2 Listes L algorithme initial que nous avons utilisé pour la création de es était le suivant : Allouer une nouvelle cellule en mémoire (2 4 octets) ; Générer le code pour la tête de la e ; Copier le résultat en mémoire dans le premier octet de la nouvelle cellule ; Générer le code pour la queue de la e (appel récursif du visiteur sur la partie droite de l arbre) ; Copier le résultat (adresse) dans la second octet de la nouvelle cellule. Exemple d exécution : Avec cet algorithme, et en partant du principe que tous les registres sont libres au moment de la création de la e, une e représentant la chaîne abcd en mémoire conduit à cette exécution : Allocation d une nouvelle cellule. Adresse stockée dans R1 ; Génération du code pour a. Stockage dans R2 ; Stockage du résultat R2 dans la cellule ; Libération de R2 ; Génération du code pour la queue bcd : Allocation d une nouvelle cellule. Adresse stockée dans R2 ; Génération du code pour b. Stockage dans R3 ; Stockage du résultat R3 dans la cellule ; Libération de R3 ; Génération du code pour la queue cd : Allocation d une nouvelle cellule. Adresse stockée dans R3 ; Génération du code pour c. Stockage dans R4 ; Stockage du résultat R4 dans la cellule ; Libération de R4 ; Génération du code pour la queue d : Allocation d une nouvelle cellule. Adresse stockée dans R4 ; Génération du code pour d. Stockage dans R5 ; Stockage du résultat R5 dans la cellule ; Libération de R5 ; Stockage du pointeur 0 (NilLit) dans la cellule ; 2

Stockage du pointeur R4 dans la cellule (R3) ; Libération de R4 ; Stockage du pointeur R3 dans la cellule (R2) ; Libération de R3 ; Stockage du pointeur R2 dans la cellule (R1) ; Libération de R2 ; Conséquence : Il apparaît clairement que la taille d une e générée de cette façon est limitée non pas par la mémoire disponible, mais par le nombre de registres! Pour nous, cela nous semblait inconcevable, surtout si l on pense que l utilisateur voudra certainement écrire des petits textes et pas uniquement stocker statiquement un ensemble de nombres dans une e. Première amélioration : Nous avons décidé d abandonner la génération récursive des es pour la faire de façon itérative. Plutôt que d allouer une cellule à la fois, pourquoi ne pas allouer directement une zone mémoire correspondant à la longueur de la e pour y stocker tous les éléments? Nous l avons donc fait et, de ce fait, le nombre de registres utilisés est devenu constant quelle que soit la longueur de la e. C est à ce moment que nous avons réfléchi aux conséquences d une telle génération. Pour la chaîne abcd, nous arrivons à cet usage de la mémoire (en partant du principe que la e est pointée par R1) : R1 Le grand cadre représente la zone mémoire qui a été allouée et qui est vue comme un seul bloc par le garbage collector. Imaginons maintenant que nous appelions la méthode tail sur cette e. Cela nous conduira à cet état de la mémoire : R1 3

Dès lors, le premier élément du bloc n est plus référencé et le garbage collector pensera, à tord, que cette zone mémoire peut être libérée. Cela ne se produira malheureusement que si la mémoire est saturée, générant donc une erreur que dans certains cas particuliers et rendant le déboguage extrêmement difficile. Seconde amélioration : Après avoir constaté cette source d erreur, nous avons été forcé, pour réussir à ne pas limiter l utilisateur avec des contraintes liées à notre compilateur, de trouver un autre algorithme, permettant à la fois de s affranchir du nombre de registres proportionnel à la longueur de la e et de la gestion de la mémoire par le garbage collector. L algorithme obtenu est le suivant : Allouer une nouvelle cellule en mémoire (2 4 octets). Le pointeur est appelé ; Générer le code pour la tête de la e ; Réserver un autre registre, appelé, qui pointera toujours sur le dernier élément de la e. Le faire pointer sur la cellule créée précédemment ; Faire une boucle sur tous les éléments de la e (à partir du deuxième) : Si la fin de la e est atteinte, placer 0 dans le second octet de la cellule pointée par ; Allouer une nouvelle cellule en mémoire ; Générer le code pour l élément actuel (la tête d une sous-e) ; Placer l adresse de cette cellule dans le second octet de la cellule pointée par ; Mettre à jour pour pointer vers cette nouvelle cellule. La fin de la e est aussi atteinte dans le cas où la sous-e n est pas directement interprétable (par exemple à cause d une opération tail ou head). Dans ce cas, cette sous-expression est générée de façon récursive en appelant le visiteur sur le sous-arbre droit et le résultat est placé dans le second octet de la cellule pointée par. L avantage de cette méthode par rapport à la précédente est que la e est créée par allocations successives de cellules, comme dans notre première version, mais de façon itérative, donc avec un nombre de registres constant. Exemple d exécution : Voici les différents états de la mémoire pour la création d une e représentant la chaîne abcd en mémoire : 4

5

1.3 Remarque Le code de génération des valeurs immédiates dans le fichier Item.java fait une distinction de cas entre les valeurs positives et négatives. Dans la première version, notre compilateur ne fournissait jamais de valeurs négatives, étant donné que les nombres négatifs ont été remplacés par une opération de type 0 valeur lors de la génération de l arbre. Cette distinction de cas a néanmoins été utilisée dès que nous avons simplifié les expressions arithmétiques (cf. ci-après). 1.4 Optimisations avancées Une phase d optimisation a été rajoutée dans le compilateur, entre l analyse et la génération de code. Cette phase est facultative. Pour l activer, il suffit de passer le paramètre -optimize au générateur de code. 1.4.1 Fonctions Probablement l optimisation la plus utile. Cette optimisation crée au moment de la phase d optimisation un graphe des dépendances des différentes 6

fonctions. Au moment de générer le code, une vérification est faite pour déterminer si la fonction a réellement besoin d être générée. Dans le cas des fonctions de base, étant donné qu elle sont inlinées, elles ne sont générées que si elles sont référencées comme paramètre d une fonction ou comme élément d une e. 1.4.2 Expressions arithmétiques Les expressions arithmétiques sont évaluées et seul le résultat est retourné. Dans le cas d une division par zéro au moment de l exécution, le code est généré avec la division par zéro et un message d avertissement est affiché sur le terminal. Dans le cas de valeur immédiate uniquement dans l un des deux nœuds, l optimisation tente néanmoins de simplifier l expression. Par exemple un appel tel que 1 * appel de fonction sera remplacé par l appel de fonction lui-même. Les multiplications par la constante 0 ne sont pas remplacés par 0 car la fonction peut très bien avoir des effets de bord. 1.4.3 Blocs conditionnels Les conditions des tests sont vérifiées et dans le cas d un résultat constant, seule la branche utile du test sera généré. Un message d avertissement est généré. 1.4.4 Boucles Cette optimisation est faite pendant la génération de code, mais uniquement si l optimisation a été activée. Le compilateur détecte les boucles infinies si la condition est une constante différente de zéro. Un message d avertissement est généré. Dans le cas de condition toujours fausse, le code complet de la boucle est supprimé avec un message d avertissement. 2 Améliorations 2.1 Grammaire 2.1.1 Caractères Nous avons rajouté la gestion des caractères interprétés comme leur code ASCII comme entité du langage MISC. En effet, dans la grammaire actuelle, si un utilisateur veut passer le caractère A à la fonction printchar par exemple, il doit écrire le code suivant : printchar(head("a")) ou alors passer directement le code ASCII du caractère à cette fonction. Désormais il est possible de taper A en lieu et place de head("a"). La 7

syntaxe est un caractère placé entre deux apostrophes. Il n existe pas de caractère d échappement. Il n est donc pas possible de taper le caractère de retour à la ligne par exemple. En particulier, l apostrophe est représentée par trois apostrophes consécutives. 2.1.2 Commentaires La gestion des commentaires sur plusieurs lignes a été ajoutée. La version proposée ne gère pas l imbrication de commentaires. Ils sont délimités, comme dans C ou Java, par /* et */. 2.2 Exécution Le paramètre -debug a été utilisé au niveau de la génération du code pour ajouter des commentaires dans le code source généré, de façon à pouvoir relire plus facilement le code assembleur. Pour pouvoir insérer des instructions, le fichier Code.java a dû être enrichi d un nouveau type d instruction : le commentaire. De cette façon, le commentaire peut être placé exactement à l endroit voulu dans le code, et non pas avant celui-ci, si nous avions utilisé la syntaxe System.out.println(). Conséquence : Du fait que les commentaires sont considérés comme des instructions, il a fallu réécrire les méthodes pc() et fixup() pour ne pas avoir de décalage dans les opérations sur les instructions (récupération de l instruction à une adresse précise,... ). 8