La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Génération de code Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)

Présentations similaires


Présentation au sujet: "Génération de code Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)"— Transcription de la présentation:

1 Génération de code Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI) http://zegour.esi.dz/ email: d_zegour@esi.dzd_zegour@esi.dz

2 Génération de code Généralités Éléments Expressions Affectations Saut et étiquette Structures de contrôle Méthodes

3 Rôles de la génération de code Génération des instructions machine Sélectionner les bonnes instructions Sélectionner les bons modes d’adressage Traduction des structures de contrôles (if, while,...) en branchement (sauts ) Allocation mémoire pour les variables locales Faire quelques optimisations Obtenir un fichier objet

4 Stratégie commune 1.Étudier la machine cible registres, formats des données, modes d’adressage, instructions, format des instructions,... 2.Concevoir les structures de données à l’exécution - pile d’exécution pour la gestion des procédures - zone de données pour les variables globales, mémoire pour l’allocation dynamique - zone pour les constantes, … 3.Implémenter le codage des instructions 4.Implémenter l’allocation des registres si nécessaire 5.Implémenter les routines de génération de code (dans l’ordre suivant) -charger les valeurs et les adresses dans les registres ( ou dans une pile) -traiter les formes x.y, a[i],... -traduire les expressions -gérer les sauts et les étiquettes -traduire les instructions -traduire les méthodes(procédures, fonctions) et le passage des paramètres

5 Langage Source Grammaires d’attributs Table des symboles Machine pivot: CLR Organisation mémoire Tables de compilation Langage pivot:CIL Langage d’assemblage Langage machine Forme interne Lexique Syntaxe Sémantique/ Génération de code Compilateur du langage Z Compilateur d’un langage objet.Net :Z# Exécution (CLR) Vérification avec un désassembleur IL (ildasm.exe ) Stratégie

6 Génération de code Généralités Eléments Expressions Affectations Saut et étiquette Structures de contrôle Méthodes

7 Les éléments Exemple Nous voulons ajouter 2 valeurs + ?? Modèle de code désiré load opérande 1 load opérande 2 add constante ldc.i4 x argument de méthode ldarg.s a variable locale ldloc.s a variable globale ldsfld T fld champ d’un objetldf ld T fld élément d’un tableau ldelem Valeur chargée sur la pile --- Selon le type de l’opérande nous devons générer différentes instructions de chargement Type d’opérandeinstruction à générer Nous avons besoin d’un descripteur, qui nous donne toutes les informations nécessaires au sujet des opérandes.

8 Les éléments Les descripteurs renferment les types et les adresses des opérandes. Après chargement de sa valeur avec ldloc.2, elle est dans la pile estack x esp estack kind adr... Stack ---... décrite par l’élément suivant Exemple variable locale x dans la zone ‘locals’ d’un état de méthode kind adr... Local 2... décrite par l’élément suivant x locals 0 1 2 3

9 Exemple: traitement des éléments La plupart des méthodes d’analyse syntaxique retourne des éléments (comme résultat de leur travail de traduction) Exemple: traduction d’une affectation x = y + z * 3;  Local 2  Con 3  Local 1  Local 0  Local 2   Stack  ldloc.2  Con 3   Stack  ldc.i4.3  Stack  mul   Stack  Local 1   Stack  ldloc.1   Stack  add  Stack  Local 0   stloc.0 Factor z3 * Term y + Expr Designator x = Statement x y z locals

10 Les sortes d’éléments Type opérandeType d’élément info sur les opérandes ConstanteConstValeur de la constante variable globaleStaticNœud de champ T fld statics valeur en pileStack--- estack esp Champ d’objetFieldNœud de champ estack esp adr T fld Élément de tableau Elem--- estack esp adr idx méthodeMethNœud de méthode argumentArgadresse adr args variable localeLocaladresse adr locals

11 La class Item (des éléments) class Item { enum Kinds { Const, Arg, Local, Static, Stack, Field, Elem, Meth } Kindskind; Structtype;// type of the operands intval;// Const: constant value intadr;// Arg, Local: address Symbolsym;// Field, Meth: Symbol node from symbol table } Constructeur pour la création des éléments public Item (Symbol sym) { type = sym.type; val = sym.val; adr = sym.adr; this.sym = sym; switch (sym.kind) { case Symbol.Kinds.Const: kind = Kinds.Const; break; case Symbol.Kinds.Arg: kind = Kinds.Arg; break; case Symbol.Kinds.Local: kind = Kinds.Local; break; case Symbol.Kinds.Global: kind = Kinds.Static; break; case Symbol.Kinds.Field: kind = Kinds.Field; break; case Symbol.Kinds.Meth: kind = Kinds.Meth; break; default: Parser.Error("cannot create Item"); } Crée un élément à partir d’un nœud de la table des symboles public Item (int val) { kind = Kinds.Const; type = Tab.intType; this.val = val; } Crée un élément à partir d’une constante

12 Chargement des valeurs (1) En entrée:une valeur décrite par un élément (Const, Arg, Local, Static,...) En sortie:charger la valeur dans la pile d’expressions Analyse des cas Selon le type de l’élément Nous générons différentes instructions de chargement public static void Load (Item x) { // method of class Code switch (x.kind) { case Item.Kinds.Const: if (x.type == Tab.nullType) il.Emit(LDNULL); else LoadConst(x.val); break; case Item.Kinds.Arg: switch (x.adr) { case 0: il.Emit(LDARG0); break;... default: il.Emit(LDARG, x.adr); break; } break; case Item.Kinds.Local: switch (x.adr) { case 0: il.Emit(LDLOC0); break;... default: il.Emit(LDLOC, x.adr); break; } break;...

13 Chargement des valeurs (2) public static void Load (Item x) { // cont.... case Item.Static: if (x.sym.fld != null) il.Emit(LDSFLD, x.sym.fld); break; case Item.Stack: break; // nothing to do (already loaded) case Item.Field: // assert: object base address is on stack if (x.sym.fld != null) il.Emit(LDFLD, x.sym.fld); break; case Item.Elem: // assert: array base address and index are on stack if (x.type == Tab.charType) il.Emit(LDELEMCHR); else if (x.type == Tab.intType) il.Emit(LDELEMINT); else if (x.type.kind == Struct.Kinds.Class) il.Emit(LDELEMREF); else Parser.Error("invalid array element type"); break; default: Error("cannot load this value"); } x.kind = Item.Kinds.Stack; } internal static void LoadConst (int n) { // method of class Code switch (n) { case -1: il.Emit(LDCM1); break; case 0: il.Emit(LDC0); break;... default: il.Emit(LDC, n); break; } L’élément résultant est toujours du type Stack

14 Exemple: chargement d’une constante Factor =number(.x = new Item(token.val);// x.kind = Const Code.Load(x);// x.kind = Stack.) Description par une ATG Visualisation val 17 kind val... Const 17... x = new Item(token.val); x esp 17 estack Stack ---... Code.Load(x); x sortie ldc.i4 17 Les modules de l’analyse syntaxique (Scan, check, etc..) ne sont pas montrés

15 Exemple: chargement d’un argument Designator =ident(.Symbol sym = Tab.Find(token.str);// sym.kind = Const | Arg | Local | Global x = new Item(sym);// x.kind = Const | Arg | Local | Static Code.Load(x);// x.kind = Stack.). kind name adr... Arg "abc" 2... sym = Tab.Find(token.str); sym kind adr... Arg 2... x = new Item(sym); x esp abc estack Description par une ATG 0 1 2 3 abc args Visualisation Stack ---... Code.Load(x); x sortie ldarg.2

16 Exemple: chargement d’une variable locale Description par une ATG Designator =ident(.Symbol sym = Tab.Find(token.str);// sym.kind = Const | Arg | Local | Global Item x = new Item(sym);// x.kind = Const | Arg | Local | Static Code.Load(x);// x.kind = Stack.). kind name adr... Local "xyz" 1... sym = Tab.Find(token.str); sym kind adr... Local 1... x = new Item(sym); x Stack ---... Code.Load(x); x sortie ldloc.1 0 1 2 3 xyz locals Visualisation esp xyz estack

17 Designator (.string name;.) =ident(.name = token.str; Item x = new Item(Tab.Find(name));.) { "." ident(.if (x.type.kind == Struct.Kinds.Class) { Code.Load(x); x.sym = Tab.FindField(token.str, x.type); x.type = x.sym.type; } else Error(name + " is not an object"); x.kind = Item.Kinds.Field;.) |... }. Chargement des champs d’objet var.f Conditions de contexte ( faire les vérifications nécessaires) Designator = ident "." ident. Le type de ident doit être une classe. ident doit être un champ du Designator. Description par une ATG Chercher token.str dans La liste de champs de x.type Crée un élément de type Field Consiste à mettre l’objet dans la pile et la création d’un item de type Field

18 Exemple: chargement d’un champ d’objet ident. Designator  x.sym  Field   Créer à partir de x et x.sym un élément de type Field kind type adr Field 0 x Int esp var f estack  Stack   Code.Load(x); kind type adr Stack --- Class - x Field "f" 0 Int esp var f estack x.sym sortie ldloc.1  Local 1   Item x = new Item(Tab.Find(name)); kind type adr Local 1 Class - x Field "f" - Int var f locals

19 Designator (.string name; Item x, y;.) =ident(.name = token.str; x = new Item(Tab.find(name));.) {... |"["(.Code.Load(x);.) Expr (.if (x.type.kind == Struct.Arr) { if (y.type != Tab.intType) Error("index must be of type int"); Code.Load(y); x.type = x.type.elemType; } else Error(name + " is not an array"); x.kind = Item.Elem;.) "]" }. Chargement des éléments d’un tableau a[i] Conditions de contexte Designator = ident "[" Expr "]". Le type de ident doit être un tableau. Le type de Expr doit être int. Description par une ATG La vérification de l’indice est faite dans la CLR crée un élément de type Elem Consiste à mettre le tableau et l’indice dans la pile et la création d’un item de type Elem

20 Exemple: chargement d’un élément de tableau identExpr[ Designator  Local 1   Item x = new Item(Tab.Find(name)); kind type adr Local 1 Arr x Int  Elem   Créer à partir de x un élément de type Elem kind type adr Elem --- x Int ]  Local 0   y = Expr(); kind type adr Local 0 y Int  Stack   Code.Load(y); kind type adr Stack --- y ldloc.0 Int a i estack  Stack   Code.Load(x); kind type adr Stack --- x Arr Int ldloc.1 a estack a i locals

21 Génération de code Généralités Éléments Expressions Affectations Saut et étiquette Structures de contrôle Méthodes

22 Compilation des expressions (Expr) Schéma pour x + y + z load x load y add load z add Description par une ATG Expr (.Item y; OpCode op;.) =("-" Term (.if (x.type != Tab.intType) Error("operand must be of type int"); if (x.kind == Item.Kinds.Const) x.val = -x.val; else { Code.Load(x); Code.il.Emit(Code.NEG); }.) |Term ) {( "+"(. op = Code.ADD;.) | "-"(. op = Code.SUB;.) )(.Code.Load(x);.) Term (.Code.Load(y); if (x.type != Tab.intType || y.type != Tab.intType) Error("operands must be of type int"); Code.il.Emit(op);.) }. conditions de contexte Expr = "-" Term. Term doit être de type int. Expr = Expr Addop Term. Expr et Term doivent être de type int.

23 Compilation des termes (Term) Term = Term Mulop Factor. Term et Factor doivent être de type int. Term (.Item y; OpCode op;.) =Factor {( "*"(.op = Code.mul;.) | "/"(.op = Code.div;.) | "%"(.op = Code.rem;.) )(.Code.Load(x);.) Factor (.Code.Load(y); if (x.type != Tab.intType || y.type != Tab.intType) Error("operands must be of type int"); Code.il.Emit(op);.) }.

24 Compilation des facteurs (Factor) Factor = "new" ident. ident doit être une une classe. Factor = "new" ident "[" Expr "]". ident doit dénoter un type. Le type de Expr doit être int. Factor =Designator // functions calls see later |number(.x = new Item(token.val);.) |charConst(.x = new Item(token.val); x.type = Tab.charType;.) |"(" Expr ")" |"new" ident(.Symbol sym = Tab.find(token.str); if (sym.kind != Symbol.Kinds.Type) Error("type expected"); Struct type = sym.type;.) ( "[" Expr "]"(.if (x.type != Tab.intType) Error("array size must be of type int"); Code.Load(x); Code.il.Emit(Code.NEWARR, type.sysType); type = new Struct(Struct.Kinds.Arr, type);.) |(.if (type.kind == Struct.Kinds.Class) Code.il.Emit(Code.NEWOBJ, sym.ctor); else { Error("class type expected"); type = Tab.noType; }.) )(.x = new Item(Item.Kinds.Stack); x.type = type;.).

25 Exemple var.f + 2 * var.g var  Local 0.f Designator var  Local 0.g Designator  Field g Factor  Field g 2 Factor  Const 2 * Term  Stack Term Factor  Field f + Expr  Stack   ldloc.0   Stack  ldfld T fld_f    Stack ldc.i4.2    Stack ldloc.0   Stack  ldfld T fld_g   Stack  mul   Stack  add var locals f g

26 Génération de code Généralités Éléments Expressions Affectations Saut et étiquette Structures de contrôle Méthodes

27 Modèles de code pour les affectations 5 cas selon le type du membre gauche de l’affectation localVar = expr;... load expr... stloc localVar globalVar = expr;... load expr... stsfld T globalVar obj.f = expr; ldloc obj... load expr... stfld T f instructions en bleu sont générées par Designator! arg = expr;... load expr... starg arg a[i] = expr; ldloc a ldloc i... load expr... stelem.i2 i4 ref Selon le type de l’élément (char, int, référence objet)

28 Compilation des affectations Condition de contexte Statement = Designator "=" Expr ";". Designator doit dénoter une variable, un élément de tableau ou un champ d’un objet. Le type de Expr doit être compatible avec le type de Designator. Description par une ATG Assignment(.Item x, y;.) =Designator // this call may already generate code "=" Expr (.Code.Load(y); if (y.type.AssignableTo(x.type)) Code.Assign(x, y); // x: Arg | Local | Static | Field | Elem else Error("incompatible types in assignment");.) ";". Compatibilité de l’affectation y est compatible avec x, si x et y ont le même type (x.type == y.type), ou x et y sont des tableaux de même de type, ou x a un type de référence (classe ou tableau) et y est null

29 Génération de code Généralités Éléments Expressions Affectations Saut et étiquette Structures de contrôle Méthodes

30 Saut conditionnel et inconditionnel Saut inconditionnel br offset Saut conditionnel... load operand1...... load operand2... beq offset si (opérande1 == opérande2) saut vers offset beq bge bgt ble blt bne.un Saut si = Saut si >= Saut si > Saut si <= Saut si < Saut si #

31 Sauts en avant et arrière Saut arrière (backward) Distance du saut Utilise 4 octets (CIL a aussi une forme courte avec un seul octet) relatif au début de la prochaine instruction (= fin de l’instruction de saut) L’adresse cible (étiquette) est déjà connue (car l’instruction à cet endroit a déjà été générée) br -7 instr Saut en avant (Forward) L’adresse cible (étiquette) n’est pas encore connue  la laisser à vide  la mettre à jour par la suite br ? La mise à jour est faite quand l’adresse devient connue br 2 instr

32 Utilisation de méthodes de ILgenerator Représentation des étiquettes de saut struct Label {... } Utilisation Label label = Code.il.DefineLabel();... Code.il.Emit(Code.BR, label);// jump to the yet undefined label (forward jump).. Code.il.MarkLabel(label);// now the branch to label leads here Les étiquettes sont gérées par ILGenerator. class ILGenerator {... Label DefineLabel ();// create a yet undefined jump label void MarkLabel (Label);// define the label at the current position in the IL stream }

33 Conditions if ( a > b )... Condition Modèle de code load a load b ble... Condition retourne l’opérateur de comparaison; la comparaison est faite dans l’instruction de saut Saut-si-vrai et Saut-si-faux Saut-si-vraiSaut si la condition est vraie Saut-si-fauxSaut si la condition est fausse Conditions L’élément Cond Condition retourne un élément avec un nouveau type Item.Kinds.Cond avec: Code de l’unité correspondant à l’opérateur de comparaison : public int relop; // Token.EQ,.GE,.GT,.LE,.LT,.NE Étiquettes spéciales de sauts : - public Label tLabel : pour les saut-si-vrai - public Label fLabel : pour les saut-si-faux nécessaire pour les conditions qui contiennent les opérateurs && et ||

34 L’élément Cond class Item { public enum Kinds { Const, Arg, Local, Static, Field, Stack, Elem, Meth, Cond } Kindskind; Structtype;// type of the operand intval;// Const: constant value intadr;// Arg, Local: address intrelop;// Cond: token code of the operator LabeltLabel;// jump label for true jumps LabelfLabel;// jump label for false jumps Symbolsym;// Field, Meth: symbol table node } Nouveau constructeur (pour les éléments Cond ) public Item (int relop, Struct type) { this.kind = Kinds.Cond; this.type = type; this.relop = relop; tLabel = Code.il.DefineLabel(); fLabel = Code.il.DefineLabel(); }

35 Génération de saut conditionnel Avec les méthodes de la classe Code Utilisation "if" "(" Condition ")"(. Code.FJump(x);.) class Code { static readonly OpCode[] brTrue = { BEQ, BGE, BGT, BLE, BLT, BNE }; static readonly OpCode[] brFalse = { BNE, BLT, BLE, BGT, BGE, BEQ };... internal static void TJump (Item x) { il.Emit(brTrue[x.relop - Token.EQ], x.tLabel); } internal static void FJump (Item x) { il.Emit(brFalse[x.relop - Token.EQ], x.fLabel); }... }

36 Génération de saut inconditionnel Avec une méthode de la classe Code class Code {... internal static void Jump (Label lab) { il.Emit(BR, lab); }... } Utilisation Label label = Code.il.DefineLabel();... Code.Jump(label);

37 Génération de code Généralités Éléments Expressions Affectations Saut et étiquette Structures de contrôle Méthodes

38 L’instruction while Modèle de code désiré whiletop: (Condition)... code for Condition... FJump end Statement... code for Statement... br top end:... Description par une ATG WhileStatement(.Item x;.) ="while"(.Label top = Code.il.DefineLabel(); top.here();.) "(" Condition ")"(.Code.FJump(x);.) Statement(.Code.Jump(top); Code.il.MarkLabel(x.fLabel);.). Exemple while (a > b) a = a - 2; 10ldloc.0 11ldloc.1 top 12ble 17ldloc.0 18ldc.i4.2 19sub 20stloc.0 21br -16 (=10) x.fLabel 26... 9 (=26)

39 L’instruction if Modèle de code désiré if (Condition)... Condition... FJump end Statement... Statement... end:... Description par une ATG IfStatement(.Item x; Label end;.) ="if" "(" Condition ")"(.Code.FJump(x);.) Statement ("else"(.end = Code.il.DefineLabel(); Code.Jump(end); Code.il.MarkLabel(x.fLabel);.) Statement(.Code.il.MarkLabel(end);.) |(.Code.il.MarkLabel(x.fLabel);.) ). Exemple if (a > b) max = a; else max = b; if (Condition)... Condition... FJump else Statement... Statement... br end elseelse: Statement... Statement... end:... 7 (=24) x.fLabel 17ldloc.0 18stloc.2 24ldloc.1 25stloc.2 10ldloc.0 11ldloc.1 12ble 19br2 (=26) 26... end

40 Fonctionne aussi pour les if emboîtés IfStatement(.Item x; Label end;.) ="if" "(" Condition ")"(.Code.FJump(x);.) Statement ("else"(.end = Code.il.DefineLabel(); Code.Jump(end); Code.il.MarkLabel(x.fLabel);.) Statement(.Code.il.MarkLabel(end);.) |(.Code.il.MarkLabel(x.fLabel);.) ).... stat... stat if (c1)... c1... FJump... elsebr... if (c2)... c2... FJump... s1... s1... elsebr... s2... s2... if (c3)... c3... FJump... s3... s3... elsebr... s4... s4...

41 Génération de code Généralités Éléments Expressions Affectations Saut et étiquette Structures de contrôle Méthodes

42 Appel de Procédure M(a, b); Ldloc.s a Ldloc.s b call T meth Les paramètres sont passés dans la pile estack Modèle du code Statement(.Item x, y;....) =Designator (ActPars (.Code.il.EmitCall(Code.CALL, x.sym.meth, null); if (x.type != Tab.noType) Code.il.Emit(Code.POP);.) |"=" Expr ";"(.....) ) |.... Description par une ATG

43 Appel de fonction c = M(a, b); ldloc.s a ldloc.s b call T meth stloc.s c La value de la fonction est retournée dans la estack Les paramètres sont passés dans la pile estack Modèle de code Factor =Designator [ActPars (.if (x.type == Tab.noType) Error("procedure called as a function"); if (x.sym == Tab.ordSym || x.sym == Tab.chrSym) ; // nothing to do else if (x.sym == Tab.lenSym) // array length Code.il.Emit(Code.LDLEN); else if (x.kind == Item.Kinds.Meth) Code.il.Emit(Code.CALL, x.sym.meth, null); x.kind = Item.Stack;.) ] |.... Description par une ATG

44 Déclaration de méthode MethodDecl(.Struct type; int n;.) =(Type |"void"(.type = Tab.noType;.) ) ident(.curMethod = Tab.Insert(Symbol.Kinds.Meth, token.str, type); Tab.openScope();.) "(" [ FormPars ] ")"(.curMethod.nArgs = Tab.topScope.nArgs; curMethod.locals = Tab.topScope.locals; Code.CreateMetadata(curMethod); if (curMethod.name == "Main") { if (curMethod.type != Tab.noType) Error("method Main must be void"); if (curMethod.nArgs != 0) Error("method Main must not have parameters"); }.) { VarDecl }(.curMethod.nLocs = Tab.topScope.nLocs; curMethod.locals = Tab.topScope.locals;.) Block (.if (curMethod.type == Tab.noType) Code.il.Emit(Code.RET); else { // end of function reached without a return statement Code.il.Emit(Code.NEWOBJ, Code.eeexCtor); Code.il.Emit(Code.THROW); } Tab.closeScope();.). Variable globale

45 Les paramètres formels Sont entrés dans la table des symboles (comme des symboles Arg de la portée de la méthode) La portée de la méthode compte leur nombre (dans nArgs) FormPars = FormPar { "," FormPar }. FormPar(.Struct type;.) =Type ident(.Tab.Insert(Symbol.Kinds.Arg, token.str, type);.).

46 Les paramètres réels Les charger dans la pile estack Vérifier la compatibilité des types entre les paramètres formels et réels Vérifier si le nombre de paramètres réels est égal au nombre de paramètres formels ActPars (.Item ap; int aPars = 0, fPars = 0;.) ="("(.if (m.kind != Item.Kinds.Meth) { Error("not a method"); m.sym = Tab.noSym; }.) fPars = m.sym.nArgs; Sym fp= m.sym.locals;.) [Expr (.Code.Load(ap); aPars++; if (fp != null && fp.kind == Symbol.Kinds.Arg) { if (!ap.type.AssignableTo(fp.type)) Error("parameter type mismatch"); fp = fp.next; }.) { "," Expr (.Code.Load(ap); aPars++; if (fp != null && fp.kind == Symbol.Kinds.Arg) { if (!ap.type.AssignableTo(fp.type)) Error("parameter type mismatch"); fp = fp.next; }.) } ](.if (aPars > fPars) Error("more actual than formal parameters"); else if (aPars < fPars) Error("less actual than formal parameters");.) ")".

47 L’instruction return Statement =... |"return" ((.if (curMethod.type == Tab.noType) Error("void method must not return a value");.) Expr (.Code.Load(x); if (x.type.AssignableTo(curMethod.type)) Error("type of return value must be assignable to method type");.) |(.if (curMethod.type != Tab.noType) Error("return value expected");.) )(.Code.il.Emit(Code.RET);.) ";".


Télécharger ppt "Génération de code Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI)"

Présentations similaires


Annonces Google