Escolar Documentos
Profissional Documentos
Cultura Documentos
Cuprins
1.INTRODUCERE IN ANALIZA PROGRAMELOR.............................................................2 2.TEHNICI DE ANALIZA A PROGRAMELOR......................................................................3 3. ANALIZA FLUXULUI DE DATE........................................................................................3 3.1 Premise: Complilator cu optimizare..................................................................................4 A. Criterii de optimizare......................................................................................................4 B. Nivele de optimizare.......................................................................................................4 C. Ce optimizari merita a fi efectuate?................................................................................5 D. Organizare unui optimizer..............................................................................................5 E. Optimizari tipice.............................................................................................................6 F. Analiza si transformare ..................................................................................................9 G. Esenta analizei programelor...........................................................................................9 H. Natura aproximarilor....................................................................................................10 Analysing the Program by Hand...................................................................................11 Analysing the Program by Hand (1).........................................................................11 Analysing the Program by Hand (2).........................................................................11 Analysing the Program by Hand (3).........................................................................12 The Best Solution......................................................................................................12 A Safe Solution but not the Best..........................................................................13 An Unsafe Solution...................................................................................................13 3.2 .Consideratii teoretice......................................................................................................14 A. Notiuni de baza.............................................................................................................14 B. Cadrul teoretic..............................................................................................................15 C. Clasificarea problemelor de analiza a fluxului de date.................................................17 3.3 Exemple relevante...........................................................................................................18 ...............................................................................................................................................18 Exemplu: Reaching definitions.....................................................................................18 Exemplu: Live variables analysis..................................................................................19 Exemplu: Available expressions...................................................................................19 Exemplu: Very busy expressions..................................................................................19 Bibliografie................................................................................................................................20
Analiza programelor a fost folosita initial in domeniul compilatoarelor, pentru optimizare; mai recent se utilizeaza in proiectarea limbajelor, pentru detectarea de erori. Scopul analizei programelor este de a deduce proprietati despre comportamentul programelor (in principiu despre corectitudine, dar si despre performanta etc.) Metoda de analiza a programelor este diferita de testare sau de simulare; se face analiza statica a codului sursa (NU executabilul; NU se ruleaza). Analiza si verificare Analiza programelor e legata tot mai mult de verificare formala. Verificarea formala stabileste ca un sistem e corect prin analiza riguroasa a unui model model matematic al sistemului. In urma verificarii rezulta proprietati specifice, detaliate despre comportament (ex. evenimentul A apare dupa evenimentul B etc.). Verificarea necesita in principiu analiza (simbolica) a scventelor de executie a modelului (explorarea spatiului starilor). Analiza statica se bazeaza pe tehnici matematice, riguroase; ea se foloseste de regula pentru proprietati mai generale, foloseste aproximatii sigure si nu exploreaza spatiul starilor programului. DEFINITIE: Analiza programelor reprezinta o serie de tehnici pentru prezicerea statica, la compilare a multimii comportamentelor dinamice (la rulare) ale programului. In general nu se poate face o analiza precisa. In consecinta, analiza trebuie sa faca aproximatii, dar in acelasi timp trebuie sa fie sigura (sa corespunda semanticii programului, si sa nu omita situatii posibile / erori). Din punct de vedere practic, analiza trebuie sa fie suficient de precisa (cu minimum de avertismente false) si eficienta (spatiu/timp) pentru trata programe de dimensiuni realiste.
Consta in tehnici cu originea in domeniul compilatoarelor; sunt folosite pentru generarea de cod (alocarea de registri) si optimizarea de cod (propagarea constantelor, factorizarea expresiilor comune, detectarea variabilelor nefolosite, etc). Ulterior, au fost unificate intr-un cadru general care permite aplicarea si la alte probleme de analiza de cod. Abordarea de baza: Construirea grafului de flux de control al programului Urmarirea modului in care proprietatile de interes se modifica pe parcursul programului (la traversarea nodurilor / muchiilor grafului).
Program sursa
Reprezentare intermediara
Cod executabil
the programmer can: profile program change algorithm transform program beyond the compiler
the compiler can: improve loops procedure calls address calculations architecture independent
the compiler can: use registers instruction selection peephole optimisation architecture dependent
A. Criterii de optimizare
optimizarea trebuie sa mentina nemodificat ceea ce face programului (scopul acestuia) - nu este permis ca pentru un set de date de intrare sa se modifice datele de iesire - nu e permis sa cauzeze erori care nu erau in programul initial (ex. Impartirea la 0) o optimizare trebuie sa imbunatateasca timpul de executie al programului cu o valoare masurabila - ocazional se fac optimizari de spatiu - nu orice optimizare reuseste sa inbunatateasca orice program - ocazional, o optimizare poate sa scada usor viteza unui program, dar e acceptabil daca se inbunatateste viteza medie. o optimizare trebuie sa merite efortul - timpul suplimentar necesar compilatorului trebuie recuperat si rasplatit la rularea codului compilat.
B. Nivele de optimizare
nivelul sursa (source level) depinde de limbaj ex:.referirea la elementele unei matrici de elemente conduce la calcule redundante programele Pascal and Fortran nu pot fi optimizate la nivelul sursa programele C permit ambele tipuri de referinte si pot fi optimizate nivelul intermediar (intermediate level: ) independent de limbaj si de arhitectura
intermediate representation
optimiser
nivel tinta / scazut (target/low level) - dependent de arhitectura e mai mica probabilitatea de a fi portabil
front end
optimiser
back end
transform ation
aim: to discover the hierarchical flow of control aim: to determine information about data aim: to determine information about data aim: to modify the program
Matrici tip ALGOL i := 0; while i <= n do j := 0; while j <= m do A[i,j] := B[i,j] + C[i,j]; j := j+1 od; i := i+1 od
while i <= n do j := 0; while j <= m do temp := Base(A) + i * (m+1) + j; Cont(temp) := Cont(Base(B) + i * (m+1) + j) + Cont(Base(C) + i * (m+1) + j); j := j+1 od; i := i+1 od
E. Optimizari tipice
Evitati calcule redundante reutilizati rezultatele disponibile mutati calculele invariante din bucle in afara acestora Evitati calcule excessive/nenecesare rezultate de care nu e nevoie rezultate care se cunosc deja la compilare Exemplu: Available Expressions Analysis
i := 0; first computation while i <= n do j := 0; while j <= m do temp := Base(A) + i*(m+1) + j; Cont(temp) := Cont(Base(B) + i*(m+1) + j) + Cont(Base(C) + i*(m+1) + j); j := j+1 od; i := i+1 re-computation od
Common subexpression elimination: t1 := i * (m+1) + j; temp := Base(A) + t1; Cont(temp) := Cont(Base(B)+t1) + Cont(Base(C)+t1);
i := 0; while i <= n do loop invariant j := 0; while j <= m do t1 := i * (m+1) + j; temp := Base(A) + t1; Cont(temp) := Cont(Base(B) + t1) + Cont(Base(C) + t1); j := j+1 od; i := i+1 od
Invariant code motion: t2 := i * (m+1); while j <= m do t1 := t2 + j; temp := ... Cont(temp) := ... j := ... od
induction variable i := 0; (variabila de while i <= n do inductie) j := 0; t2 := i * (m+1); while j <= m do t1 := t2 + j; temp := Base(A) + t1; Cont(temp) := Cont(Base(B) + t1) + Cont(Base(C) + t1); j := j+1 od; i := i+1 od
Exemplu:Copy Analysis
i := 0; t3 := 0; while i <= n do t2 = t3 j := 0; t2 := t3; while j <= m do t1 := t2 + j; temp := Base(A) + t1; Cont(temp) := Cont(Base(B) + t1) + Cont(Base(C) + t1); j := j+1 od; i := i+1; t3 := t3 + (m+1) od
i := 0; t3 := 0; while i <= n do dead variable (variabila neutilizata) j := 0; t2 := t3; while j <= m do t1 := t3 + j; temp := Base(A) + t1; Cont(temp) := Cont(Base(B) + t1) + Cont(Base(C) + t1); j := j+1 od; i := i+1; t3 := t3 + (m+1) od
Dead code elimination: i := 0; t3 := 0; while i <= n do j := 0; while j <= m do t1 := t3 + j; temp := Base(A) + t1; Cont(temp) := Cont(Base(B) + t1) + Cont(Base(C) + t1); j := j+1 od; i := i+1; t3 := t3 + (m+1) od
F. Analiza si transformare
Analiza fluxului de date Available expressions analysis
(Analiza expresiilor in uz)
Strength reduction
(reducerea acestora)
Copy analysis
(analiza copiilor)
Copy propagation
(propagarea copiilor)
statica, la compilare: aproximatii sigure & eficiente ale setului de configurari sau comportamente ce pot aparea dinamica, la rulare . Sigur: = fidel semanticii Eficient: = implementare cu performanta buna de timp si consum mic de spatiu
H. Natura aproximarilor
univers
overapproximation (supraaproximare)
underapproximation (subaproximare)
unacceptable!
Reguli: Eroarea sa fie spre supraaproximare! Eficienta e mai importanta decat precizia! (Error on the safe side!) (Trade precision for efficiency!)
Exemplu:
10
Program cu etichete pentru blocurile elementare: [y := x]1; [z := 1]2; while [y > 0]3 do [z := z y]4; [y := y 1]5 od; [y := 0]6
Flow graph:
[y := 0]6
[z := z y]4
[y := y 1]5
{(x, ?), (y, ?), (z, ?)} {(x, ?), (y, 1), (z, ?)} {(x, ?), (y, 1), (z, 2)} U {(y, 5), (z, 4)} {(x, ?), (y, 1), (z, 2)} {(x, ?), (y, 1), (z, 4)} {(x, ?), (y, 5), (z, 4)} {(x, ?), (y, 1), (z, 2)}
Analysing the Program by Hand (3) [y := x]1; [z := 1]2; while [y > 0]3 do [z := z y]4; [y := y 1]5 od; [y := 0]6 {(x, ?), (y, 6), (z, 2), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4) } {(x, ?), (y, 5), (z, 4)} {(x, ?), (y, 1), (y,5), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4)} U {(y, 5), (z, 4)} {(x, ?), (y, 1), (z, ?)} {(x, ?), (y, ?), (z, ?)}
The Best Solution {(x, ?), (y, ?), (z, ?)} {(x, ?), (y, 1), (z, ?)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4)}
12
[z := z y]4; [y := y 1]5 od; [y := 0]6 {(x, ?), (y, 6), (z, 2), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4) } {(x, ?), (y, 5), (z, 4)} {(x, ?), (y, 1), (y,5), (z, 4)}
A Safe Solution but not the Best [y := x]1; [z := 1]2; while [y > 0]3 do [z := z y]4; [y := y 1]5 od; [y := 0]6 An Unsafe Solution [y := x]1; [z := 1]2; while [y > 0]3 do [z := z y]4; [y := y 1]5 od; [y := 0]6 {(x, ?), (y, 6), (z, 2), (z, 4)} * secventele marcate in ultimul exemplu se exclud {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4) } {(x, ?), (y, 5), (z, 4)} {(x, ?), (y, 1), (y,5), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4)} {(x, ?), (y, 1), (z, ?)} {(x, ?), (y, ?), (z, ?)} {(x, ?), (y, 6), (z, 2), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4) } {(x, ?), (y,1), (y, 5), (z,2), (z, 4)} {(x, ?), (y, 1), (y,5), (z,2), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4)} {(x, ?), (y, 1), (z, 2), (y, 5), (z, 4)} {(x, ?), (y, 1), (z, ?)} {(x, ?), (y, ?), (z, ?)}
13
14
B. Cadrul teoretic
. Analiza fluxului de date se realizeaz prin executarea de operatii asupra unei structuri algebrice denumita latice. Laticea este o multime partial ordonata(reflexiva, tranzitiva, antisimetrica), in care orice submultime finita are un cel mai mic majorant(least upper bound) si un cel mai mare minorant (greatest upper bound). -l0 este majorant al lui Y L daca pentru orice l Y avem l l0 -l0 este minorant al lui Y L daca pentru orice l Y avem l l0 Notam: UY cel mai mic majorant al multimii Y L Y cel mai mare minorant al multimii Y L si =U=L T==UL (vezi proprietatea 5). Elementele laticei reprezint proprietti abstracte ale variabilelor, expresiilor sau altor componente din program. Fiecrei unitti din program (instructiune, basic block sau procedur) i se asociaz un element de latice care memoreaz propriettile urmrite de analiz, referitoare la acel punct din program. Aceste proprietti se refer la toate executiile posibile ale unei proceduri, fr a tine seama de datele de intrare si de drumurile n graful fluxului de control al procedurii. Ceea ce avem n vedere aici este c cele mai multe metode de analiz de date nu tin cont de faptul c o conditie este indeplinita sau nu, si astfel dac ramura then sau else a unui if este executat, sau de cate ori se execut o bucl. Informatiile vor fi conservative, trebuie ca pe baza lor sa nu se trag concluzii gresite asupra programului si deci sa se opereze transformari care sa fac programul incorect. In general o latice L este format dintr-o multime de valori si dou operatii pe care le vom nota ("meet") si U ("join") si care au urmtoarele proprietti: 1. Pentru orice x, y . L exista z . L si w . L unici, astfel nct x y = z si x U y = w (nchidere) 2. Pentru orice x, y . L, x y = y x si x U y = y U x (comutativitate) 3. Pentru orice x, y, z . L, (x y) n z = x (y z) si (x U y) U z = x U (y U z) (asociativitate) 4. Pentru orice x, y . L, (x y) U y = y si (x U y) x = x (absorbtia) 5. Exista doua elemente unice ale lui L, pe care le numim min (notat ) si max (notat T ), astfel nct pentru orice x L, x = si x U T = T (unicitatea existentei elementelor de minim si maxim). 6. Numeroase latici sunt si distributive, adic pentru orice x, y, z L, avem: (x y) U z = (x U z) (y U z) si (x U y) z = (x z) U (y z). In cazul analizei de date, cele mai multe dintre laticile folosite au ca elemente constituente vectori de biti iar operatiile de baz sunt reprezentate de operatiile AND (meet) si OR (join) aplicate pe biti. Elementul al unei astfel de latici este vectorul de biti n care toti bitii sunt 0 iar elementul T n acest caz este vectorul n care toti bitii sunt 1. Folosim notatia BVn pentru a desemna o latice de vectori de biti de lungime n. Operatiile U si introduc o relatie de ordine partiala pe elementele laticei, pe care o vom nota Aceasta relatie poate fi definita folosind operatia astfel: x y x y = x. Se poate da si 15
o definitie duala folosind operatia U. Urmatoarele proprietati ale relatiei se demonstreaz cu usurinta pe baza propriettilor operatiilor U si : 1. Pentru orice x L, x x. (reflexivitate) 2. Pentru orice x, y L, dac x y si y x atunci x = y. (antisimetrie) 3. Pentru orice x, y, z L, dac x y si y z, atunci x z. (tranzitivitate) In mod corespunzator se definesc si relatiile <,>,. O functie ce mapeaza laticea pe ea insasi (f : L L) este monotona dac pentru orice x, y L, x y => f(x) f(y). De exemplu functia f:BV3 BV3 definita prin f(<x1x2x3>) = <x11x3> este monotona. Inaltimea unei latice este lungimea celui mai lung lant strict cresctor din latice, adica cel mai mare n astfel nct = x1 < x2 < < xn = T. Pentru a modela efectul pe care l are fiecare component a programului asupra elementelor de latice, se defineste o asa numita functie de flux. Cte o functie de flux se asociaza fiecrei instructiuni, fiecrui basic block sau fiecrei proceduri. O functie de flux asociat unei instructiuni primeste ca parametru un element de latice si intoarce elementul de latice transformat n urma executiei instructiunii respective. O functie de flux asociata unui bloc de baza are ca intrare de asemenea un elemnt de latice si intoarce elementul de latice asa cum ar fi el transformat n urma executiei blocului respectiv. Practic functia de flux asociata unui basic block este compusa functiilor de flux associate instructiunilor din bloc. Fie s o instructiune si F(s):LL functia de transfer asociata care determina modul in care valoarea proprietatii la inceputul instructiunii e modificata de instructiune. Vom avea: Propout(s)=F(s)(Propin(s)) pentru analize inainte sau invers pentru analize inapoi. Pentru a putea rezolva o problema de analiza de flux de date impunem ca toate functiile de flux sa fie monotone. Aceasta este rezonabil tinand cont ca scopul unei functii de flux este sa modeleze informatia (despre problema de flux de date) oferita de o portiune de program si deci nu ar trebui sa scada informatia deja obtinuta(daca stim mai multe despre argument, atunci si despre rezultat). Monotonicitatea este de asemenea esentiala pentru a demonstra ca algoritmii de analiza a fluxului de date se termina si pentru a calcula complexitatea lor. Portiunea de program modelata de o functie de flux poate varia, n functie de cerintele noastre, de la o singura instructiune la intreaga procedur. Prin ecuatii de flux intelegem un sistem de forma: Propout(s)=F(s)(Propin(s)) Propin(s)=spred(s) Propout(s) unde prin am reprezentat efectul combinarii informatiilor(meet) pe mai multe cai (ar putea fii sau U). Initial este cunoscuta valoarea Propout(entry). Pentru analize inapoi se schimba rolul intre in si out, si e cunoscuta valoarea Propin(exit). Un punct fix al unei functii f:L L este un element z L astfel nct f(z) = z. Pentru un set de ecuatii de flux de date un punct fix este o solutie a setului de ecuatii deoarece aplicand partea dreapta a ecuatiilor asupra punctului fix vom obtine aceeasi valoare. In multe cazuri, o functie definita pe o latice poate avea mai multe puncte fixe. Cel mai simplu exemplu este functia definita pe BV cu f(0)=0 si f(1)=1. Evident si 0 si 1 sunt puncte fixe.
16
Valoarea pe care vrem sa o calculam cand rezolvam un set de ecuatii de flux de date este asanumita solutie "meet-over-all-paths (MOP). Fie G = < N, E > un CFG (control flow graph) si Path(B) multimea tuturor cailor de la entry la B, B N. Fie p un element oarecare din Path(B), FB functia de flux reprezentand fluxul prin blocul B si FP compunerea functiilor de flux intalnite pe calea p. Adica, daca B1 = entry, ,Bn =B sunt blocurile ce constituie calea p atunci FP = FBn ooFB1. Fie Init valoarea din latice asociata cu blocul entry. Atunci, solutia MOP este: MOP(B)=Fp(Init), pentru B = entry, B1, ,Bn, exit. Ecuatii similare exprima solutia MOP pentru probleme de flux invers. Din nefericire nu este dificil de aratat ca pentru o problema arbitrara de analiza de flux de date n care functiile de flux sunt monotone s-ar putea sa nu existe nici un algoritm care sa calculeze solutia MOP pentru toate CFG-urile posibile. Ceea ce calculeaza algoritmii prezentati n continuare este de fapt solutia MFP(maximum-fixed-point), care este solutia maximala a ecuatiilor de flux de date raportat la relatia de ordine a laticei, adica altfel spus, solutia care ofer cat mai multa informatie. S-a demonstrat ca n problemele de flux de date n care functiile de flux sunt distributive, algoritmul iterativ dat aici calculeaza solutia MFP care n acest caz este identica cu solutia MOP.
Folosirile expuse (exposed uses). Este problema duala celei de mai sus. Aceasta determina, pentru fiecare punct al programului n care este definit o variabil, ce folosiri ale variabilei pot utiliza acea definire (sunt expuse acelei definiri). Este o problema de tip inapoi si foloseste o lattice de vectori de biti, n care fiecarui bit i este asociata o folosire a unei variabile. Expresiile disponibile (available expressions). Scopul acestei probleme este determinarea expresiilor disponibile n fiecare punct din procedur, n sensul ca pe orice cale, de la intrarea n procedur pana n acel punct, are loc o evaluare a expresiei si nici una din variabilele folosite n expresie nu primeste o valoare noua intre ultima evaluare a expresiei si respectivul punct din program. Aceasta este o problema de tip inainte care foloseste o latice de vectori de biti n care fiecare bit este asociat unei definiri a unei expresii. Variabilele n viat (live variables). Aceasta analiza determina pentru o anumita variabila si un anumit punct din program daca mai exista o folosire a valorii variabile pana la iesirea din procedur. Aceasta este o problema de tip inapoi si elementul de latice este un vector de biti n care fiecare bit este asociat unei variabile. Propagarea copierilor (copy propagation). Aceasta analiz determina daca pe fiecare cale de la o copiere a unei variabile x . y la o folosire a variabilei x, valoarea lui y ramane neschimbata. Aceasta este o problema de tip inainte care foloseste vectori de biti iar fiecare bit reprezint o copiere a unei variabile. Propagarea constantelor (constant propagation). Problema are ca scop determinarea valorii unei variabile intr-un anumit punct, dac aceasta valoare este constanta. Problema e de tip inainte si nu foloseste o latice de vectori de biti. Analiza partiala a redundantei (partial redundancy). Determina ce calcule se efectueaza de mai multe ori pe o anumita cale de executie, fara ca operanzii sa se fi modificat intre timp. De asemenea se determina si definirile redundante (nefolosite) ale unei variabile. Problema este de tip bidirectional si foloseste vectori de biti n care fiecare pozitie reprezint o calculare a expresiei. Problemele de mai sus nu sunt singurele de analiza de date dar sunt cele mai importante. Exista mai multe abordari n rezolvarea problemelor de flux de date.
- definitiile de la intrarea unei instructiuni sunt reuniunea definitiilor de la iesirea instructiunilor precedente: RDin(s) = U (spred(s)) RDout(s) Exemplu: Live variables analysis In fiecare punct de program, care sunt variabilele ale caror valoare va fi folosita pe cel putin una din caile posibile din acel punct ? (analiza utila in compilatoare pentru alocarea registrilor). Functia de transfer: LVin(s) = ( LVout(s) \ write(s)) U read(s) (o variabila e live inainte de s daca e citita de s, sau e live dupa s fara a fi scrisa de s ) => sensul analizei e inapoi Operatia de combinare (meet): ; daca succ(s) = LV _eout(s) =
U(s succ(s)) LV ein(s) altfel => combinarea facuta prin uniune (may, pe cel putin o cale). Calculul: algoritm de tip worklist care face modificari pornind de la valorile initiale pana nu mai apar schimbari ) se atinge un punct fix. Exemplu: Available expressions In fiecare punct de program, care sunt expresiile a caror valoare a fost calculata anterior, fara sa se fi modificat, pe toate caile spre acel punct? (daca valoarea se tine minte intr-un registru, nu trebuie recalculata) Functia de transfer: AEout(s) = (AEin(s) \ { e | V (e) write(s) }) U {e Subexp(s) | V (e) write(s) = } (expresiile de la intrarea in s care nu au variabile modificate de s, si orice expresii calculate in s fara a li se modifica variabilele) Operatia de combinare (meet): ; daca pred(s) = AEin(s) =
( s pred(s)) AEout(s) altfel => combinarea e facuta prin intersectie (must, pe toate caile); analiza e inainte Exemplu: Very busy expressions Care sunt expresiile care trebuie evaluate pe orice cale din punctul curent inainte ca valoarea vreunei variabile din ele sa se modifice ? => evaluarea se poate muta in punctul curent, inainte de ramificatii =>o analiza inapoi, si de tip universal (must) VBEin(s) = (VBEout(s) \ { e | V (e) write(s) }) U Subexp(s) , daca succ(s) = V BEout(s) =
{
(s succ(s)) VBEin(s) altfel
19
Bibliografie
20