Po roku od ostatniej, wprowadzającej nową funkcjonalność, wersji kolekcji kompilatorów GNU oczom naszym ukazała się wersja 4.0. Było o niej głośno jeszcze wtedy, gdy była oznaczana przez programistów gcc jako 3.5. Czego możemy spodziewać się po tej wersji?

Killer features

Asy nowego GCC są już powszechnie znane: możliwość ukrywania symboli, listy umiejscowienia obiektów (location lists) oraz włączenie gałęzi tree-ssa do głównego drzewa GCC.

-fvisibility

Ukrywanie symboli, od dawna dostępne w systemie Windows (np. poprzez __declspec(dllexport)) jest istotnym narzędziem w procesie tworzenia bibliotek. Daje ono bowiem realną kontrole programiście nad tym, które funkcje lub obiekty jego biblioteka udostępnia. Domyślnie tablica symboli zawiera wszystkie symbole, które są globalnie dostępne w bibliotece, przez co większość bibliotek jest przerośnięta – zawiera niepotrzebnie eksportowane symbole. Eksportowane winny być tylko te klasy, które istotnie stanowią część API. Istotnie przyśpiesza to także czas ładowania bibliotek, gdyż tablice symboli i ich nazw muszą być przy ładowaniu wczytane. Stąd prosty wniosek, im mniej niepotrzebnych obiektów zawierają, tym lepiej. Dokładniejsze opisy jak stosować -fvisibility i __attribute((visibility(scope)))__ można znaleźć w „doskonałym howto o pisaniu bibliotek” (http://people.redhat.com/drepper/dsohowto.pdf) autorstwa Ulricha Dreppera (maintainera glibc) oraz w artykule (http://gcc.gnu.org/wiki/Visibility) autora patcha dodającego obsługę visibility.

Dodatkowo wygodną opcją, która można bezpiecznie włączyć jest -fvisibility-inlines-hidden, która sprawia, że wszystkie funkcje inline otrzymają atrybut hidden – nie będą eksportowane do tablicy symboli, co przynajmniej trochę zmniejszy bibliotekę i czas jej ładowania (choć w większości przypadków to nie funkcje inline zajmują najwięcej niepotrzebnego miejsca, więc i zysk może nie być największy). Opcja ta oczywiście działa tylko w C++, podczas gdy sam __attribute((visibility(scope)))__ działa w C i C++.

lista umiejscowienia obiektów

Podczas kompilacji z włączonymi jednocześnie parametrami -g (i jego wariantami) oraz jakąkolwiek kombinacją -fomit-frame-pointer,-O1,-O2,-O3; GCC włączy tworzenie tzw. location lists, czyli listy obiektów zawierającej informacje o ich położeniu przed dokonaniem przez kompilator operacji, która to położenie mogła zmieniać (np. ominięcie frame pointer lub optymalizacja inline). Dzięki temu możliwe jest odtąd debugowanie programów skompilowanych np. z -g3 -O2, co jest wygodne w tym względzie, że jeśli informacje do debugowania wyrzucimy później do innego pliku, to mamy wówczas program bliski skompilowanemu bez -g3 ale tylko z -O2.

Obsługa location lists została dodana w gdb 6.1.

tree-ssa

Parser GCC zyskał dwa silne narzędzia w GCC4, które mają znacznie wesprzeć optymalizacje. Single Static Assignment (SSA) to technologia polegająca na przypisywaniu każdej zmiennej dokładnie jednej definicji w programie. W ten sposób zmienna i o różnych wartościach w dwóch różnych miejscach staje się dwoma różnymi zmiennymi, zatem niezwiązane ze sobą dwa wykorzystania tej samej zmiennej stają się różnymi zmiennymi, co eliminuje niepotrzebną zależność. Dobrze pokazuje to następujący przykład

Typowe przetwarzanie Single Static Assignment
i=0 i0 = 0
i=i+1 i1 = i0 +1
j=funkcja(i) j0=funkcja(i1)
i=2 i2 = 2

W oparciu o SSA dodano stworzono zupełnie nowy parser, który obsługuje:

  • skalarne przedstawianie agregatów
  • propagację stałych oraz zakresu zmiennych
  • częściową eliminacje nadmiarowych instrukcji

i inne techniki optymalizacji.

Oprócz tego dodano Swing Modulo Scheduling (SMS) – instrukcje na poziomie RTL (języka kompilatora) optymalizującą pętle które wykonują złożone obliczenia.

Pozostałe zmiany

  1. C++

    • dodano wsparcie „C++ ABI” (http://www.codesourcery.com/cxx-abi/) – co daje m.in. bezpieczną dla wątków inicjalizację zmiennych statycznych w zakresie lokalnym funkcji
    • dodano obsługę deklarowania zagnieżdżonych w klasach szablonów zawierających klasy jako friend
  2. Java

    • rozszerzona obsługa AWT i SWING, SAX, JAXP, DOM oraz wiele nowych klas
    • GCJ może pracować jako JIT
    • opcja -findirect-dispatch powoduje, że GCJ generuje kod binarnie kompatybilny ze specyfikacją Java Language Specification
  3. Fortran

    • stary frontend do języka Fortran 77 został zastąpiony nowym, wspierającym Fortran 90,95 oraz generalnie lepszym pod względem parsowania i optymalizacji
  4. Ada

    • wiele poprawek oraz wsparcie dla niektórych rozszerzeń Ada 2005
  5. Usunięto następujące flagi kompilatora:

    • -fwritable-strings
    • -freduce-all-givs, -fmove-all-movables – workaroundy dla braku niektórych optymalizacji w kompilatorze Fortran, optymalizacje są w nowym kompilatorze, więc workaroundy stały się niepotrzebne
    • -mv8, -msparclite, -mcypress, -msupersparc, -mf930 oraz -mf934, zastąpiono przez -mcpu=odpowiedniprocesor
    • a także -membedded-pic, -mrnames (specyficzne flagi dla architektury MIPS)
  6. Usprawnienia dla konkretnych platform

    • funkcje matematyczne na IA-32/x86-64 przy włączeniu -ffast-math wykorzystują x87 instrincs
    • liczne optymalizacje na IA-64, MIPS i S/390, H8/300
    • SPARC wspiera Visual Instruction Set (VIS) Sun’a
    • na UltraSPARC uaktualniono model liczenia kosztu wykonania poszczególnych instrukcji (przyśpieszenie na nowszych UltraSPARCach)
    • Novell Netware dodany do wspieranych platform, ABI GCC na Netware zostało zsynchronizowane z ABI udostępnianym przez MetroWerks CodeWarrior
    • porzucono platformy: SPARClite, SPARC OpenBSD 32bit, Intel i860, Ubicom IP2022 i National Semiconductor NS32K

Błędy

Niestety tak wielki projekt jak GCC nie mógł ustrzec się wszystkich błędów, przed wydaniem GCC 4.0 pojawiło się kilka krytycznych błędów powodujących poważne miskompilacje.

  1. Krytyczne:

    • R19317 – usuwanie tymczasowej wartości, gdy to nie jest dozwolone (workaround wyłączający optymalizacje na tym znalazł się GCC 4.0, bug jednak będzie poprawiony dopiero w GCC 4.1, nie wiadomo czy zostanie poprawiony także w GCC 4.0.1)

    • PR20973 – krytyczna miskompilacja KDE, choć bug poprawiony to poprawka nie znalazła się w GCC 4.0 (będzie w 4.0.1 i 4.1), w GCC 4.0 konieczne jest nałożenie „tego patcha”. Są duże szanse, że ta miskompilacja dotyczy nie tylko KDE, więc lepiej i tak go nałożyć.

  2. Pozostałe warte odnotowania

    • PR17640 – pusta pętla nie jest usuwana po optymalizacji

    • PR20128 – Internal Compiler Erorr podczas budowania aplikacji używającej libmudflap z włączonym profilowaniem

Nie jest również możliwe skompilowanie glibca 2.3.4 i wcześniejszych za pomocą GCC4, wspierane wersje glibca zaczynają się od tej, która aktualnie znajduje się w repozytorium CVS projektu glibc.

Sprawdź sam!

Zarówno owa wersja glibca, działające z nim poprawnie binutils oraz gcc z poprawką na PR20973 są dostępne w bootstrapowanej właśnie wersji PLD 3.0 na architektury: i486, x86-64, i686, athlon, PowerPC. Użytkownicy dystrybucji opartych na Debianie mogą zainstalować GCC 4.0 z gałęzi debian/experimental za pomocą polecenia: apt-get install -t experimental gcc-4.0

Archiwalny news dodany przez użytkownika: djurban.
Kliknij tutaj by zobaczyć archiwalne komentarze.

Oznaczone jako → 
Share →