Single Static Assignment
Single Static Assignment to postać programu używana przez kompilatory w trakcie optymalizacji, w której każdej zmiennej wartość przypisuje się tylko raz.
Np. dla programu:
a = read(); b = a + 2; a = a + 1; f(a, b);
Postać SSA to:
a1 = read(); b1 = a1 + 2; a2 = a1 + 1; f(a2, b1);
Jeśli wartość zmiennej w danym użyciu może pochodzić z kilku różnych przypisań, używa się specjalnej funkcji Φ.
Dla:
a = 2;
if (b > 0)
a = 4;
f(a);
Postacią SSA jest:
a1 = 2;
if (b > 0)
a2 = 4;
a3 = Φ(a1, a2);
f(a3);
Postać SSA ułatwia wiele rodzajów optymalizacji. Najprostszą jest propagacja stałych – jeśli wiemy, że do danej zmiennej SSA została przypisana pewna wartość, możemy zastąpić wszystkie użycia tej zmiennej przez daną stałą, nawet jeśli w oryginalnym programie zmienna ta była używana też do innych celów.
Więzy
Można też na tej postaci dokonywać łatwych wyliczeń więzów.
Np. jeśli wiemy, że w programie jest wykonywany test czy a3 > 0, i że a3 = Φ(a1, a2),
możemy sprawdzić czy test ten jest spełniony nawet bez znajomości dokładnej wartości a3.
Np. jeśli mamy kod tablicujący wartości funkcji sinus:
int rozmiar = 100; float tab[rozmiar];
i = 0;
while (i < rozmiar)
{
tab[i] = sin(i * alpha);
i = i + 1;
}
Bezpieczeństwo wymaga, żeby wprowadzić testy, czy używany indeks jest poprawny (powinien to robić automatycznie kompilator; większość kompilatorów C/C++ tego nie robi, choć robią to kompilatory wielu innych języków):
int rozmiar = 100; float tab[rozmiar];
i = 0;
while (i < rozmiar)
{
if (i < 0)
raise InvalidArrayIndex;
if (i >= rozmiar)
raise InvalidArrayIndex;
tab[i] = sin(i * alpha);
i = i + 1;
}
Po zmianie formy na SSA (blok pre-while oznacza instrukcje wykonywane przed porównaniem, blok taki nie występuje w kodzie źródłowym, jednak kompilator musi go wygenerować, żeby umieścić tam wyliczenia i wywołania funkcji występujące w złożonych warunkach):
int rozmiar = 100; float tab[rozmiar];
i1 = 0;
pre-while {
i3 = Φ(i1, i2);
}
while (i3 < rozmiar)
{
if (i3 < 0)
raise InvalidArrayIndex;
if (i3 >= rozmiar)
raise InvalidArrayIndex;
tab[i] = sin(i3 * alpha);
i2 = i3 + 1;
}
To że i3 >= rozmiar jest fałszywe kompilator wie z
warunku, jaki występuje na początku bloku. Jednak i musi w trakcie wykonywania programu przynajmniej raz złamać to założenie – osiąga przecież wartość rozmiar żeby opuścić pętlę! Bez SSA trudniej byłoby rozważać takie przypadki. Podobnie kompilator może stwierdzić, że i1 >= 0, i że jeśli i3 >= 0, to
i2 = i3 + 1 >= 0 (jeśli zajmie się też rozpatrywaniem kwestii przepełnienia).
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.