Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi...

28
Tecnologie dei Linguaggi Artificiali 1 Introduzione 2 Analisi lessicale 3 Analisi sintattica 4 Analisi semantica 5 Generazione di codice 6 Ambienti runtime Aho, Lam, Sethi, Ullman “Compilers. Principles, Techniques, and Tools”, Addison-Wesley, 2006 Levine “Flex & Bison”, O’Reilly, 2009. Materiale in rete : http://gianfranco-lamperti.unibs.it Tecnologie dei Linguaggi Artificiali 1. Introduzione 1

Transcript of Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi...

Page 1: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Tecnologie dei Linguaggi Artificiali

1 Introduzione

2 Analisi lessicale

3 Analisi sintattica

4 Analisi semantica

5 Generazione di codice

6 Ambienti runtime

Aho, Lam, Sethi, Ullman “Compilers. Principles, Techniques, and Tools”, Addison-Wesley, 2006

Levine “Flex & Bison”, O’Reilly, 2009.

Materiale in rete : http://gianfranco­lamperti.unibs.it

Tecnologie dei Linguaggi Artificiali 1. Introduzione 1

Page 2: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Background Storico

Link

Fine 1940s: primi elaboratori basati sulla architettura di von Neumann necessario scrittura di programmi = [ istruzioni ]

Codice macchina: =

Linguaggio Assembly:

“Idealmente”: specifica di operazioni in forma concisa

Obiezioni storiche

Tecnologie dei Linguaggi Artificiali 1. Introduzione 2

linguaggi di programmazione

tecnologia di implementazioneprocesso di astrazione possibile

C7  06  0000  0002istruzione esadecimale di Intel 8x86 per inserire il numero 2 all'indirizzo 0000

MOV X, 2tradotto in linguaggio macchina da un assemblatore

difficile da capire

non portabile

notazione matematica (espressioni)

linguaggio naturale (controllo)

X = 2

impossibilese possibile codice target inefficiente

contraddette dal FORTRAN

Page 3: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Processori dei Linguaggi

● Anche: traduttori source-to-source (es: C++ C)

Tecnologie dei Linguaggi Artificiali 1. Introduzione 3

Compilatoreprogramma sorgente (L sorgente)

Interpreteprogramma sorgente

programma target (L target)

inputoutput

Traduttoreprogramma

sorgente

programma intermedio Macchina

Virtualeinputoutput

CompilatoreJust-in-time

programma target

programma intermedio

(programma)

Page 4: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Processori dei Linguaggi (ii)

Fattori di complessità apparente nella progettazione di tecniche generali:

1. Migliaia di L sorgente

2. Migliaia di L target

3. Svariate tipologie di compilatori (passata singola / multipla, diversi raggruppamenti delle fasi ...)

Ad un certo livello di astrazione complessità ridotta a poche procedure essenziali fanno uso delle stesse tecniche

Tecniche per compilatori riusabili in altri contesti della scienza informatica

Domini di interesse:

Tecnologie dei Linguaggi Artificiali 1. Introduzione 4

L di programmazione (source-to-source)

L macchina

Teoria dei linguaggi artificiali

Linguaggi di programmazione

Web

Architetture hardware

Algoritmi

Ingegneria del software

Page 5: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Implementazione dei Linguaggi di Programmazione

L di programmazione di alto livello: più facili da usare ma meno efficienti

L di programmazione di basso livello: più efficienti ma più difficili da usare, programmi meno portabili, più esposti a errori, più difficili da manutenere

Compilatori ottimizzanti tecniche per migliorare l'efficienza del codice generato

Esempio: register keyword in C: considerato necessario (1970s) per controllare quali variabili risiedono nei registri Non più necessaria con tecniche efficaci di allocazione dei registri "Cablare" l'allocazione dei registri può inficiare le prestazioni!

Tecnologie dei Linguaggi Artificiali 1. Introduzione 5

Page 6: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Ottimizzazioni per Architetture degli Elaboratori

Rapida evoluzione delle architetture degli elaboratori richiesta di nuove tecnologie dei compilatori

Sistemi hw ad alte prestazioni si avvantaggiano con

Parallelismo:

- Compilatore può riarrangiare le istruzioni per rendere più efficace il parallelismo a livello di istruzione supportato dall'hardware

- Se parallelismo a livello di istruzione incluso nel set di istruzioni (istruzioni con operazioni multiple in parallelo) tecniche dei compilatori per generare codice per tali macchine da programmi sequenziali

- Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore

Gerarchie di memoria: registri + caches + memoria fisica + memoria secondaria

- Gestione della cache da parte dell'hw: non efficace nel codice scientifico operante su grossi array tecniche dei compilatori per cambiare il layout dei dati o l'ordine delle istruzioni che accedono ai dati miglioramento della efficacia delle gerarchie di memoria

Tecnologie dei Linguaggi Artificiali 1. Introduzione 6

parallelismo

gerarchie di memoria

Page 7: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Traduzione di Programmi

Traduzione fra diversi tipi di linguaggi

Traduzione Binaria: da codice binario di una macchina a codice binario di un'altra macchina (tipicamente, per aumentare la disponibilità del sw prodotto)

Sintesi Hardware: progettazioni hw descritte in L di alto livello di descrizione hw (VHDL, RTL) traduzione mediante strumenti di sintesi hw in schemi hw dettagliati

Traduttori di Query: query di alto livello tradotta in azioni di ricerca di record (SQL Algebra Relazionale Azioni per ricerca fisica)

Simulazione Compilata: invece di scrivere un simulatore che interpreta il progetto (costoso), meglio compilare il progetto in codice macchina che simula quel progetto

Tecnologie dei Linguaggi Artificiali 1. Introduzione 7

Page 8: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Contesto di un Compilatore

Tecnologie dei Linguaggi Artificiali 1. Introduzione 8

programma sorgente scheletrico

preprocessore

programma sorgente

compilatore

programma target Assembly

assemblatore

codice macchina rilocabile

linker / loader

codice macchina assoluto

libreria, file oggetto rilocabili

composizione da file multipli

macro-sostituzione

Page 9: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Modello di Compilazione

Separazione

Analisi operazioni nel programma sorgente mappate su struttura gerarchica albero sintattico

Tecnologie dei Linguaggi Artificiali 1. Introduzione 9

analisi: riconoscimento parole + rappresentazione interna del sorgente (albero sintattico)

sintesi: costruzione del programma target più specializzato (e complesso)

P P’

partenza

distanza

distanza := partenza + 20 * tempo

distanza

:=

+

partenza *

20 tempo

velocità = 20

Page 10: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Analisi del Programma Sorgente

Analisi lessicale (lineare) raggruppamento di caratteri in simboli [ token ]

Analisi sintattica (gerarchica) simboli grammaticali raggruppati gerarchicamente albero sintattico

Analisi semantica controllo di consistenza

Tecnologie dei Linguaggi Artificiali 1. Introduzione 10

type checking

inserimento di informazioni nella symbol table

Page 11: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Fasi di un Compilatore Fase = unità concettuale in cui opera un compilatore: Rap(P sorgente) Rap’(P sorgente)

Tecnologie dei Linguaggi Artificiali 1. Introduzione 11

programma sorgente

Analizzatore lessicale

Analizzatore semantico

Generatore di codice intermedio

Ottimizzatore di codice intermedio

Generatore di codice

Gestore della symbol table

Gestore degli errori

handler

1

3

4

5

6

programma target

Ottimizzatore di codice7

Analizzatore sintattico2

Page 12: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Symbol Table

Struttura dati contenente informazioni sugli identificatori (catalogo)

Requisiti

Esempio d'uso:

Tecnologie dei Linguaggi Artificiali 1. Introduzione 12

iddistanzapartenzatempo

attributi (informazione rilevante)

spazio allocatotiposcopese nome procedura

numero di parametritipi dei parametrimetodo di passaggio dei p.[ tipo del par. di ritorno ]

accesso efficiente agli attributi degli identificatori

aggiornamento incrementale degli attributi

lettura

scrittura

var distanza, partenza, tempo: real; Lexer inserisce gli identificatori, ma tipo conosciuto solo dopo (sem)

SEM: type checkingGEN: spazio allocato in memoria

Page 13: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Gestione degli Errori

fase F gestione degli errori pertinenti a F (separazione delle pertinenze)

Tecnologie dei Linguaggi Artificiali 1. Introduzione 13

LEX unknown symbol: @

SYN if a := 5 then 

SEM y := x + s

integer

string

RUNTIME *p := 10

null

Page 14: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Trasformazione del Programma Sorgente

Stessa computazione espressa in diversi livelli di astrazione

1. Analisi lessicale

Riconoscimento dei terminali coppie (simbolo, valore)

Rimozione di spaziatura / commenti

Codifica di ogni simbolo (:= #define ASSIGN 257)

Alcuni simboli estesi con valore lessicale (id “distanza”, oppure puntatore alla symbol table)

Tecnologie dei Linguaggi Artificiali 1. Introduzione 14

distanza := partenza + 20 * tempo

id1 := id2 + 20 * id3

Page 15: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Trasformazione del Programma Sorgente (ii)

2. Analisi sintattica

(token, child, brother)

Tecnologie dei Linguaggi Artificiali 1. Introduzione 15

id1

:=

+

id2 *

20 id3

id1 := id2 + 20 * id3

:= nil

+ nil

id2 nil * nil

20 nil id3 nil nil

Uniformità dei nodi pbdisomogeneitàcardinalità della prole

union

binarizzazione

id1 nil

Page 16: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Trasformazione del Programma Sorgente (iii)

3. Analisi semantica

Rivisitazione dell'albero per controllo dei vincoli semantici (tipi consistenti con le operazioni)

Possibile decorazione / alterazione dell'albero

Tecnologie dei Linguaggi Artificiali 1. Introduzione 16

id1

:=

+

id2 *

20

id3toreal

id1

:=

+

id2 *

20 id3

Page 17: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Trasformazione del Programma Sorgente (iv)

4. Generazione codice intermedio una istruzione per ogni operatore dell'albero sintattico

Codice intermedio = programma scritto nel linguaggio di una macchina astratta (virtuale)

Proprietà: facile da

Vantaggi

Natura: diversificata, tipicamente: codice a tre indirizzi (quadruple) Assembly in cui locazioni di memoria viste come registri

al più un operatore esplicito (oltre l'assegnamento) linearizzazione delle operazioni Generazione di temporanei per risultati intermedi Non necessariamente tre operandi (anche meno, es. toreal)

Tecnologie dei Linguaggi Artificiali 1. Introduzione 17

t1 := toreal(20)t2 := t1 * id3

t3 := id2 + t2

id1 := t3

id1

:=

+

id2 *

20

id3toreal

generare

semplificazione della implementazione

operator addr1 addr2 addr3 * addr1 addr2 addr3 addr3 := addr1 * addr2

semantica operazionale

tradurre in codice target

portabilità (riusabilità)

Page 18: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Trasformazione del Programma Sorgente (v)

5. Ottimizzazione del codice intermedio riduzione del numero di istruzioni

Codice intermedio più efficiente (es: conversione 20 20.0 può essere fatta staticamente!)

Problema: rallentamento della compilazione (per ottimizzazioni avanzate)

Possibili diversi livelli di ottimizzazione

Meglio non ottimizzare durante la codifica (tempo, debugging)

Dopo l'ottimizzazione rifare il testing

Tecnologie dei Linguaggi Artificiali 1. Introduzione 18

t1 := toreal(20)t2 := t1 * id3

t3 := id2 + t2

id1 := t3

t := 20.0 * id3

id1 := id2 + t

Page 19: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Trasformazione del Programma Sorgente (vi)

6. Generazione di codice necessario caricamento dei registri per effettuare le operazioni

Tipo di codice target

In generale: mapping

Tecnologie dei Linguaggi Artificiali 1. Introduzione 19

LDF R2, id3

MULF R2, R2, #20.0LDF R1, id2

ADDF R1, R1, R2

STF id1, R1

t := 20.0 * id3

id1 := id2 + t

Assembly (tipicamente)Macchina rilocabile variabili trasformate in locazioni di memoria

istruzioni istruzioni macchina equivalenti

variabili registri (per operazioni)

Page 20: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Raggruppamento delle Fasi di un Compilatore

Organizzazione logica organizzazione fisica (come nei DB)

Front-End: dipende solo dal sorgente LEX, SYN, SEM, GEN-I [, parte di OPT-I ]

Back-End: dipende solo dal target OPT-I, GEN, OPT

Macro-modularizzazione: utile per il porting del compilatore (macro-moduli riusabili)

Tecnologie dei Linguaggi Artificiali 1. Introduzione 20

FrontEnd

BackEnd

codice intermedio

(interfaccia)

codice targetcodice sorgente

Idealmente: cambiandoL sorgente cambiamento del Front-End

L target cambiamento del Back-Endcodice intermedio: invariante

Page 21: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Raggruppamento delle Fasi di un Compilatore (ii)

Possibili scenari:

1. Stesso L su piattaforme (realistico) F

2. L su stessa piattaforma (ideale): B

3. L su piattaforme:

Tecnologie dei Linguaggi Artificiali 1. Introduzione 21

B1

B2

...Bn

F1

F2

...Fm

F1

F2

...Fm

B1

B2

...Bn

(nm) moduli invece che (m*n) compilatori

Page 22: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Bootstrapping & Porting

L coinvolti in un compilatore

Cross-compilatore: quando Comp(a) gira su una macchina target (necessario quando macchina target con risorse limitate)

codice target non eseguibile sulla stessa macchina

Tecnologie dei Linguaggi Artificiali 1. Introduzione 22

Compilatore del linguaggio a, scritto in

sorgente

target

implementazione (host)

Linguaggio macchina nei primi compilatori

Compilatore di Compilatore (eseguibile) di a

a = Ada

= C

target = IntelComp(a) su AMD

(bootstrapping)

Page 23: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Bootstrapping & Porting (ii)

Diagramma a T: per schematizzare un compilatore (mediante i 3 linguaggi coinvolti)

Composizione dei diagrammi (per generare nuovi compilatori):

1. Concatenazione

2. Incastro

Tecnologie dei Linguaggi Artificiali 1. Introduzione 23

S T

H

H = Linguaggio macchina dell'eseguibile

H T cross-compilatore

a

H

H

a

H

a

H

M

H K

a

K

(Cambiamento del linguaggio target) a = Ada

= C

H = PascalK = Fortran

(Cambiamento del linguaggio host)

Page 24: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Bootstrapping & Porting (iii)

Note (3 tipi di bootstrapping):

Bootstrapping del cross-compilatore

Compilatore scritto nel linguaggio sorgente che compila ! Pb di bootstrapping !

Tecnologie dei Linguaggi Artificiali 1. Introduzione 24

Compilatore del linguaggio a, scritto in

Compilatore di Compilatore (eseguibile) di a

a H

H

Ha

H

H

a H

K

Ka

K

H

S T

S

(bootstrapping)

Page 25: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Bootstrapping & Porting (iv)

Raggiro della circolarità:

Limiti di BAD:

Unico requisito per BAD: correttezza funzionale del codice generato

Tecnologie dei Linguaggi Artificiali 1. Introduzione 25

GOOD = compilatore di S scritto in S

BAD = compilatore di S’ S scritto in Assembly

Compila solo un subset di S (relativo alla implementazione di GOOD)Inefficiente a runtimeGenera codice target inefficiente

efficientegenera codice target efficiente

spazio

tempo

GOOD+

BAD

GOOD

Page 26: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Bootstrapping & Porting (v)

Bootstrapping (alchimia):

1. Scrittura in Assembly di un compilatore “quick & dirty” (BAD) per subset di S usato per scrivere GOOD

2. Compilazione di GOOD mediante BAD NOTGOOD

3. Compilazione di GOOD mediante NOTGOOD GOOD

Tecnologie dei Linguaggi Artificiali 1. Introduzione 26

T

T

T

T

TSS S

GOODBAD S

NOTGOOD

compila ogni programma scritto in S

genera codice target efficiente!

inefficiente (runtime)

T

T

T

T

TSS S

GOODNOTGOOD

S

GOOD

Requisito di correttezza funzionale per il codice generato da BAD

compila ogni programma scritto in S

generata codice target efficiente

efficiente (runtime)

Page 27: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Bootstrapping & Porting (vi)

Dopo bootstrapping compilatore specificato in 2 forme

Vantaggi:

a) Miglioramento di GOOD GOOD+ immediatamente boostrappato dai passi 2 e 3 in GOOD+

b) Porting di GOOD su un nuovo host computer riscritto solo il Back-End di GOOD GOOD’

Tecnologie dei Linguaggi Artificiali 1. Introduzione 27

sorgente S = GOOD

target T = GOOD

T

T

T

T

TSS S

GOOD+GOOD

S

NOTGOOD+T

T

T

T

TSS S

GOOD+NOTGOOD+

S

GOOD+

+

T’

T

T

T

T’SS S

GOOD’GOOD

S

CROSS’

+ T’

T

T’

T’

T’SS S

GOOD’CROSS’

S

GOOD’

Page 28: Tecnologie dei Linguaggi Artificiali · - Tecniche di parallelizzazione per tradurre programmi sequenziali in codice multiprocessore Gerarchie di memoria: registri + caches + memoria

Bootstrapping & Porting (vii)

Considerazioni simili quando “quick & dirty” scritto in linguaggio di alto livello S

1.

2.

3.

Tecnologie dei Linguaggi Artificiali 1. Introduzione 28

Ada

Ada

T

Ada

C

T

C

T

T

Ada

T

T

BAD BAD

Ada

Ada

T

Ada

T

T

Ada

T

T

GOOD NOTGOOD

BAD

Ada

Ada

T

Ada

T

T

Ada

T

T

GOOD GOOD

NOTGOOD