Rapport de TER: Analyse de pointeur dans LLVM



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

Gestion mémoire et Représentation intermédiaire

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Grandes lignes ASTRÉE. Logiciels critiques. Outils de certification classiques. Inspection manuelle. Definition. Test

TP1 : Initiation à Java et Eclipse

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

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)

Introduction à MATLAB R

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Algorithmique, Structures de données et langage C

Algorithmique et Programmation, IMA

Rapport de Synthèse. Création d un Générateur de modèle PADL pour le langage C++ Sébastien Colladon


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

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Chapitre VI- La validation de la composition.

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Généralités sur le Langage Java et éléments syntaxiques.

SSTIC Désobfuscation automatique de binaires. Alexandre Gazet. Yoann Guillot. Et autres idyles bucoliques...

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Évaluation et implémentation des langages

Analyse de sécurité de logiciels système par typage statique

Les structures de données. Rajae El Ouazzani

Programmation C++ (débutant)/instructions for, while et do...while

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Cours d initiation à la programmation en C++ Johann Cuenin

Introduction au langage C

Cours Programmation Système

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Cours 1 : La compilation

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Argument-fetching dataflow machine de G.R. Gao et J.B. Dennis (McGill, 1988) = machine dataflow sans flux de données

30.avr.10 Présentation miniprojet. 9.mars.10 Cours 3 4.mai.10 Cours C mars.10 Cours 4 11.mai.10 Cours C++ 2

V- Manipulations de nombres en binaire

Java et les bases de données: JDBC: Java DataBase Connectivity SQLJ: Embedded SQL in Java. Michel Bonjour

Cours d Algorithmique et de Langage C v 3.0

Conception des systèmes répartis

PROJET ALGORITHMIQUE ET PROGRAMMATION II

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

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

Cours Informatique Master STEP

Compilation (INF 564)

SQL Parser XML Xquery : Approche de détection des injections SQL

LES OUTILS D ALIMENTATION DU REFERENTIEL DE DB-MAIN

Auto-évaluation Programmation en Java

Initiation à JAVA et à la programmation objet.

Vérification formelle de la plate-forme Java Card

I. Introduction aux fonctions : les fonctions standards

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

Cours de Système : Gestion de Fichiers

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Chap III : Les tableaux

Le langage C. Séance n 4

Plan global Outils de développement et compilation. Plan. Objectifs des outils présentés. IDE, GCC/Clang, ASAN, perf, valgrind, GDB.

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

UE Programmation Impérative Licence 2ème Année

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Conventions d écriture et outils de mise au point

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

Notes du cours 4M056 Programmation en C et C++ Vincent Lemaire et Damien Simon

Cours d algorithmique pour la classe de 2nde

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Rappels sur les suites - Algorithme

Premiers Pas en Programmation Objet : les Classes et les Objets

Objets et Programmation. origine des langages orientés-objet

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

Master (filière Réseau) Parcours Recherche: Systèmes Informatiques et Réseaux (RTS)

Cours de Programmation 2

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

Une dérivation du paradigme de réécriture de multiensembles pour l'architecture de processeur graphique GPU

FLEX 3. Applications Internet riches avec Flash ActionScript 3, MXML et Flex Builder. Aurélien Vannieuwenhuyze

Compression de Données - Algorithme de Huffman Document de Conception

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

Plan du cours Cours théoriques. 29 septembre 2014

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

3. SPÉCIFICATIONS DU LOGICIEL. de l'expression des besoins à la conception. Spécifications fonctionnelles Analyse fonctionnelle et méthodes

Génie Logiciel avec Ada. 4 février 2013

IFT2255 : Génie logiciel

Chapitre 1 : La gestion dynamique de la mémoire

Devenez un véritable développeur web en 3 mois!

TP1. Outils Java Eléments de correction

Programmation en langage C

Programmation système de commandes en C

Cours 14 Les fichiers

Les structures. Chapitre 3

3IS - Système d'exploitation linux - Programmation système

SQL Server 2012 Implémentation d'une solution de Business Intelligence (Sql Server, Analysis Services...)

Java Licence Professionnelle CISII,

Métriques de performance pour les algorithmes et programmes parallèles

Traduction des Langages : Le Compilateur Micro Java

27/11/12 Nature. SDK Python et Java pour le développement de services ACCORD Module(s)

Programmer en JAVA. par Tama

Architecture des Systèmes d Information Architecture des Systèmes d Information

Reconstruction de bâtiments en 3D à partir de nuages de points LIDAR

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

Transcription:

Rapport de TER: Analyse de pointeur dans LLVM Aurélien CHEMIER Janvier-Février 2014 Résumé Les optimisations réalisées à l intérieur d un compilateur, pour améliorer l efficacité du code généré, ont besoin d informations détectées statiquement (taille des tableaux, variables constantes, etc). Certaines de ces analyses très utiles, ne fonctionnent que dans des cas "syntaxiquement simples". L objectif de ce TER est d améliorer le domaine d application des optimisations de tableaux réalisées dans l équipe Compsys. En effet, ces optimisations sont pour le moment restreintes à des tableaux de taille statique, et à des programmes qui ne contiennent aucune utilisation de pointeurs. Or, on constate souvent que les pointeurs ne sont utilisés en C que de façon rudimentaire : transmission d arguments par adresses, allocation dynamique de tableau réalisée une unique fois, descripteurs de tableaux, pseudo-indices. L objectif est donc de réaliser un outil de détection de ces usages simples et de transformer le programme initial en un programme sémantiquement équivalent qu on pourra ensuite optimiser en utilisant les outils de l équipe. Mots clefs : Optimisation, pointeurs, C Table des matières 1 Introduction 2 2 Analyse Statique de code avec LLVM/Clang 2 2.1 Le framework LLVM/Clang.................................. 2 2.2 Représentation des instructions dans LLVM/Clang.................... 2 2.3 Travail existant......................................... 3 2.4 Critiques à l utilisation de Clang............................... 4 3 Transformation source à source à sémantique constante 5 3.1 Rappel du problème...................................... 5 3.1.1 Exemple 1 : pointeur constant sur variable..................... 5 3.1.2 Exemple 2 : pointeur sur tableau........................... 5 3.1.3 Exemple 3 : pointeur sur tableau (cas 2)....................... 6 3.2 Étude de solutions possibles.................................. 7 3.2.1 La modification du CFG ou de l AST........................ 7 3.2.2 La modification à l impression du programme................... 9 4 Conclusion 9 1

1 Introduction Mif20 - UCBL - 2013/2014 2 L avancée technologique des plateformes matérielles, avec des caractéristiques toujours plus complexes, rend nécessaire des analyses toujours plus fines du code source, que ce soit pour des buts d optimisation à la compilation (optimisation de taille mémoire, de l usage du cache...) ou d optimisations lors de l exécution. COMPSYS est une équipe-projet de recherche commune à Inria et au Laboratoire de l Informatique du Parallélisme (LIP). Elle est localisée à l Ecole Normale Supérieure de Lyon (ENS Lyon). L objectif de Compsys est le développement de techniques de compilation, plus précisément d optimisations de codes, appliquées aux domaine des systèmes embarqués de calcul (embedded computing systems). Les optimisations de code réalisées dans l équipe Compsys s effectuent pour la plupart au niveau des parcours de tableaux (optimisations dites polyédriques). Elles ont pour but de favoriser le parallélisme, la localité (pour éviter les défauts de cache), et d optimiser les chargement de données. Cependant, pour des raisons de simplicité, les optimisations ne sont pour l instant appliquées qu à des programmes sans pointeurs, et dans lequel les tableaux sont déclarés statiquement. Or, dans un programme C, l utilisation des pointeurs est souvent basique (tableau dynamique,...). En reconnaissant certaines utilisations simples de pointeurs dans les programmes, il sera possible de modifier le code pour utiliser les optimisations déjà écrites. Durant son stage de L3, Christophe Bacara a démarré une implémentation d outils et d algorithmes permettant de caractériser les utilisations de pointeur d un code C donné. Il utilise pour cela le framework Clang/LLVM. Le résultat 1 est un stockage dans une structure de données d un certain nombre d informations concernant les pointeurs du programme (pointeurs constants, pointeurs "cachant" des tableaux). L objectif du TER était donc d utiliser les informations statiquement récupérées dans le programme C pour transformer ce code C en un programme équivalent. Ce TER a été encadré par Laure Gonnord. 2 Analyse Statique de code avec LLVM/Clang 2.1 Le framework LLVM/Clang Le projet LLVM3 est né en 2000 à l Université de l Illinois, sous la direction de Chris Lattner et Vikram Adve. Il s agit d une infrastructure de compilateur, fondée sur une représentation intermédiaire du code, de type SSA (single static assignment, conçue pour l optimisation d un programme à tous les niveaux (analyse, compilation, édition de liens, exécution). LLVM est composé de librairies qui permettent de manipuler cette représentation du code. A l origine, l implémentation concernait les langages C et C++, mais il existe désormais une grande variétés de frontend 2 : Ruby, Python,Java, PHP, et Fortran, parmi d autres. LLVM contient nombre d optimisations, ainsi que des générateurs de code pour de nombreux processeurs. LLVM est diffusé sous licence University Of Illinois Open Source, licence de type BSD. LLVM est codé en C++. Clang (codé en C++) et est le front-end de LLVM. C est celui qui est chargé de faire les analyses lexicales et syntaxiques, de construire l arbre de syntaxe abstrait du programme, et de le convertir en code intermédiaire, compréhensible par LLVM. 2.2 Représentation des instructions dans LLVM/Clang Clang utilise une hiérarchie de classes pour représenter les différentes instructions rencontrées dans un programme. Stmt est la super-classe de cette hiérarchie, et représente de manière abstraite n importe quelle instruction. Une partie de cette architecture est présentée dans la figure 1 1. http://laure.gonnord.org/pro/papers/rapportbacara.pdf 2. Passes de compilation qui effectuent l analyse lexicale et syntaxique de la source en entrée afin de la transformer en représentation intermédiaire, nécessaire à la suite du processus de compilation (optimisation, édition de liens,...) Rapport de TER de Aurélien CHEMIER 2

Mif20 - UCBL - 2013/2014 3 FIGURE 1 Partie de l architecture de Clang De plus, Stmt, ainsi que toutes les classes qui en héritent, se comporte comme un conteneur. Elle peut donc stocker des pointeurs vers des objets enfants de type Stmt (et donc, par polymorphisme 3, de n importe quelle classe héritant de Stmt). Ainsi, en itérant sur un objet de type Stmt, il est possible de récupérer l ensemble des sous-instructions contenues dans cet objet. Un exemple de représentation d une instruction est disponible avec la figure 2. FIGURE 2 Représentation d une instruction étudié par Clang 2.3 Travail existant Le travail de C. Bacara m a permis d avoir à ma disposition différents outils pour l étude des pointeurs dans un code C. 3. Principe de programmation orientée objet, qui considère qu un objet d une classe B, héritant d une classe A, peutêtre considéré comme une extension de la classe A, et peut donc être manipulé comme un objet de classe A. Rapport de TER de Aurélien CHEMIER 3

Mif20 - UCBL - 2013/2014 4 La fabrication et le parcours du CFG (Graphe de flot de contrôle, voir figure 3 par exemple) du code à optimiser. Les pointeurs constants : c est à dire les pointeurs dont la valeur ne change pas dans la fonction étudié. Pour celà, il faut parcourir le CFG, une fois celui-ci créé, et contrôler la nonmodification de la valeur des pointeurs. Les alias de pointeurs : c est à dire lorsque plusieurs pointeurs désignent le même objet. Pour stocker les informations d alias et de pointeur constant, Christophe Bacara a utilisé une structure donnée faisant appel à un codage matriciel (qui lui permet de coder le graphe orienté de la relation pointe sur ). Par exemple pour le code suivant : Listing 1 Code exemple pour les matrices d alias int main() { int *p1, *p2, *p3 = p2, *p4 = p2; int n; p0_1 = &n; L analyseur créera d abord une matrice carré avec les pointeurs et les cibles pointés. Les lignes indiquent les pointeurs et les colonnes les cibles. 1 0 0 0 0 1 0 0 0 1 1 0 0 1 0 1 Ensuite, on créé la matrice symétrique de la matrice précédente. En effet dans l exemple, on a le pointeur p3 qui pointe sur p2, donc, si on connaît p2, on connaît également p3. 1 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 Dernière étape, il faut prendre en compte les pointeurs qui pointent sur une même cible (a pointe sur b, c pointe sur b...) et les suites de pointeurs. (a pointe sur b qui pointe sur c...). Une clôture transitive est donc implémentée : 1 0 0 0 0 1 1 1 0 1 1 1 0 1 1 1 Ainsi avec cette matrice, on connaît tous les alias du code. 2.4 Critiques à l utilisation de Clang La librairie Clang permet de parser le code C étudié et d obtenir à la fois l arbre de syntaxe abstraite (AST) et le graphe de flot de contrôle (CFG). Une fois qu on dispose de l AST/CFG, il est facile de vérifier l utilisation faite des pointeurs. Et donc de manière générale, d obtenir des informations statiques sur les constructions syntaxiques du programme, ce qui est fait par le code existant de C. Bacara. Dans la suite, ce que l on désire faire est une modification de cette structure d AST ou de CFG, par exemple en remplacement un statement (affectation, test,... ) par un autre. Il faudra donc modifier cette structure interne. La librairie Clang fournit des fonctions génériques de parcours, mais pas Rapport de TER de Aurélien CHEMIER 4

Mif20 - UCBL - 2013/2014 5 des fonctions de modification (en tout cas pas au même niveau d utilisation). La modification sera donc plus complexe que la recherche d information. 3 Transformation source à source à sémantique constante 3.1 Rappel du problème L objectif du TER est de trouver certaines utilisations spécifiques des pointeurs dans le but de les optimiser. Dans cette partie nous analysons les différentes transformations simples que nous désirons réaliser. 3.1.1 Exemple 1 : pointeur constant sur variable Cet exemple traite de l optimisation dans le cas d un pointeur constant. Listing 2 Exemple de pointeur constant int a = 1, b = a + 1; int *p = a; while (*p < b) { if (b % 2 == 0) b++; else *p *= 2; Dans cet exemple, on voit bien que le pointeur p est un alias de a. Quand on modifie la valeur pointé par p, a est modifié et réciproquement. Le travail d optimisation consiste à voir que le pointeur p est constant et qu il est un alias de a. Et de là, on remplace toutes les occurences de p par a. Avec le travail déjà effectué, on peut récupérer le fait que p est un alias a et il suffit de modifier le rewriter pour appliquer l optimisation. int a = 1, b = a + 1; Listing 3 Optimisation de l exemple précédent while (a < b) { if (b % 2 == 0) b++; else a *= 2; 3.1.2 Exemple 2 : pointeur sur tableau Cet exemple traite de l optimisation dans le cas d un pointeur sur un tableau. #include <stdio.h> #include <stdlib.h> #include <time.h> Listing 4 Exemple de pointeur sur un tableau Rapport de TER de Aurélien CHEMIER 5

int *t = malloc(100*sizeof(int)); int i,j; int min,temp; Mif20 - UCBL - 2013/2014 6 srand(time(null)); for(i=0; i < 100; i++){ nombre_aleatoire = rand_a_b(1, N); t[i] = rand()%(b-a) +a; for(i =0; i < 100; i++){ min = i; for(j = i; j < 100; j++){ if(t[j] < t[min]) min = j; temp = t[i] ; free(t); t[i] = t[min] ; t[min] = temp; Le code de Christophe Bacara permet de voir que le pointeur est initialisé avec le malloc et qu il n est pas modifié jusqu à la fin du programme. Il suffit de modifier le pointeur en tableau statique de taille N. int t[100]; Listing 5 Optimisation de l exemple précédent 3.1.3 Exemple 3 : pointeur sur tableau (cas 2) Cet exemple traite de l optimisation dans le cas d incrément sur le pointeur d un tableau. #include <stdio.h> #include <stdlib.h> #include <time.h> Listing 6 Exemple de pointeur constant int *t = malloc(100*sizeof(int)); int i,j; int min,temp; srand(time(null)); for(i=0; i < 100; i++){ nombre_aleatoire = rand_a_b(1, N); *(t+i) = rand()%(b-a) +a for(i=0; i < 100; i++){ min = i; for(j = i; j < 100; j++){ if(*(t+j) < *(t+min)) min = j; temp = *(t+i) ; *(t+i) = *(t+min) ; *(t+min) = temp; Rapport de TER de Aurélien CHEMIER 6

Mif20 - UCBL - 2013/2014 7 free(t); De la même manière que l exemple précédent, on peut répérer le malloc et le non-changement de la valeur de t. Ensuite, il faut remarquer les incréments utilisés pour visiter les cases du tableau. #include <stdio.h> #include <stdlib.h> #include <time.h> Listing 7 Optimisation de l exemple précédent int t[100]; int i,j; int min,temp; srand(time(null)); for(i=0; i < 100; i++){ nombre_aleatoire = rand_a_b(1, N); t[i] = rand()%(b-a) +a; for(i =0; i < 100; i++){ min = i; for(j = i; j < 100; j++){ if(t[j] < t[min]) min = j; temp = t[i] ; free(t); t[i] = t[min] ; t[min] = temp; 3.2 Étude de solutions possibles Pour modifier le code, trois méthodes sont possibles : La première est l utilisation d un script shell. Il semble difficile de réaliser de telles transformations sans s appuyer sur la structure du code fournie par Clang/LLVM, donc cette solution n a pas été retenue. 3.2.1 La modification du CFG ou de l AST Lors du parcours du programme par LLVM/Clang, un graphe de flot de contrôle est créé. Par exemple pour le code suivant : Listing 8 Exemple de pointeur constant int a = 1, b = a + 1; int *p = a; while (*p < b) { if (b % 2 == 0) Rapport de TER de Aurélien CHEMIER 7

Mif20 - UCBL - 2013/2014 8 b++; else *p *= 2; On obtient le CFG (figure 3). FIGURE 3 CFG du code exemple Avec les informations obtenues pour ce graphe par C. Bacara, il est possible de modifier le graphe de flot de la manière suivante : FIGURE 4 CFG du code exemple Rapport de TER de Aurélien CHEMIER 8

Mif20 - UCBL - 2013/2014 9 Ainsi lors de la réécriture du programme, le code est modifié. Cette réécriture peut être effectué grâce à la classe Rewriter de LLVM qui permet grâce à des fonctions de haut niveau d imprimer le CFG (inserttext(),replacetext()...). 3.2.2 La modification à l impression du programme Elle consiste à parcourir le CFG, à récupérer les données (par exemple dans une matrice pour les alias (voir 2.3) et ensuite faire les modifications lors de l écriture du fichier sortie. C est la méthode que j ai choisie d utiliser car elle est plus simple et rapide à mettre en oeuvre. 4 Conclusion LLVM est un outil très pratique à utiliser pour analyser un code source. Grâce à ce framework et à une implémentation adaptée, on peut connaître les différentes propriétés d un code C. Au cours de ce TER, j ai pu mettre en oeuvre le cas d un pointeur constant pour modifier les utilisations de ce pointeur dans le programme et ainsi permettre la suite des optimisations. Néanmoins l algorithme permettant la modification des pointeurs n a pas été implémenté. Lors de ce stage, j ai pu découvrir le milieu de la recherche informatique, et j ai beaucoup appris en terme de compilation avancée. De plus j ai pu dévellopé mes compétences en C++ et j ai découvert le framework LLVM qui pourra peut-être me servir plus tard. Rapport de TER de Aurélien CHEMIER 9