Wydanie zestawu kompilatorów GCC 11

Po roku rozwoju wydano darmowy pakiet kompilatorów GCC 11.1, pierwsze znaczące wydanie w nowej gałęzi GCC 11.x. Zgodnie z nowym schematem numeracji wydań, wersja 11.0 była używana podczas opracowywania, a na krótko przed wydaniem GCC 11.1 gałąź GCC 12.0 została już rozwidlona, ​​z której zostanie utworzone kolejne znaczące wydanie GCC 12.1.

GCC 11.1 wyróżnia się przejściem na domyślny format pliku debugowania DWARF 5, domyślnym włączeniem standardu C++17 („-std=gnu++17”), znaczącymi ulepszeniami w obsłudze C++20 standard, eksperymentalne wsparcie dla C++23, ulepszenia związane z przyszłym standardem języka C (C2x), nowe optymalizacje wydajności.

Główne zmiany:

  • Domyślny tryb języka C++ został przełączony tak, aby korzystał ze standardu C++17 (-std=gnu++17) zamiast oferowanego wcześniej C++14. Możliwe jest selektywne wyłączenie nowego zachowania C++ 17 podczas przetwarzania szablonów, które używają innych szablonów jako parametru (-fno-new-ttp-matching).
  • Dodano obsługę przyspieszania sprzętowego narzędzia AddressSanitizer, które pozwala określić fakty dotyczące dostępu do zwolnionych obszarów pamięci, przekraczania granic przydzielonego bufora i niektórych innych rodzajów błędów podczas pracy z pamięcią. Akceleracja sprzętowa jest obecnie dostępna tylko dla architektury AArch64 i koncentruje się na użyciu podczas kompilacji jądra Linuksa. Aby włączyć akcelerację sprzętową programu AddressSanitizer podczas budowania komponentów przestrzeni użytkownika, dodano flagę „-fsanitize=hwaddress” i flagę jądra „-fsanitize=kernel-hwaddress”.
  • Podczas generowania informacji debugowania domyślnie używany jest format DWARF 5, który w porównaniu do poprzednich wersji umożliwia generowanie o 25% bardziej zwartych danych debugowania. Pełna obsługa DWARF 5 wymaga wersji binutils co najmniej 2.35.2. Format DWARF 5 jest obsługiwany w narzędziach do debugowania od GDB 8.0, valgrind 3.17.0, elfutils 0.172 i dwz 0.14. Aby wygenerować pliki debugowania przy użyciu innych wersji DWARF, możesz użyć opcji „-gdwarf-2”, „-gdwarf-3” i „-gdwarf-4”.
  • Zwiększono wymagania dla kompilatorów, których można użyć do zbudowania GCC. Kompilator musi teraz obsługiwać standard C++11 (wcześniej wymagany był C++98), czyli: Jeśli GCC 10 wystarczyło do zbudowania GCC 3.4, to do zbudowania GCC 11 potrzebny jest teraz przynajmniej GCC 4.8.
  • Zmieniono nazwę i lokalizację plików do zapisywania zrzutów, plików tymczasowych i dodatkowych informacji niezbędnych do optymalizacji LTO. Takie pliki są teraz zawsze zapisywane w bieżącym katalogu, chyba że ścieżka zostanie wyraźnie zmieniona za pomocą opcji „-dumpbase”, „-dumpdir” i „-save-temps=*”.
  • Obsługa formatu binarnego BRIG do użytku z językiem HSAIL (język pośredni architektury heterogenicznej architektury systemu) została przestarzała i wkrótce zostanie usunięta.
  • Rozszerzono możliwości trybu ThreadSanitizer (-fsanitize=wątek), zaprojektowanego w celu wykrywania sytuacji wyścigowych podczas udostępniania tych samych danych z różnych wątków aplikacji wielowątkowej. Nowa wersja dodaje obsługę alternatywnych środowisk wykonawczych i środowisk, a także obsługę narzędzia do debugowania KCSAN (Kernel Concurrency Sanitizer), zaprojektowanego w celu dynamicznego wykrywania warunków wyścigu w jądrze Linuksa. Dodano nowe opcje „-param tsan-distinguish-volatile” i „-param tsan-instrument-func-entry-exit”.
  • Numery kolumn w komunikatach diagnostycznych odzwierciedlają teraz nie liczbę bajtów od początku linii, ale tak naprawdę numery kolumn, które uwzględniają znaki wielobajtowe oraz znaki zajmujące kilka pozycji w linii (np. znak 🙂 zajmuje dwie pozycje i jest zakodowany w 4 bajtach). Podobnie znaki tabulacji są teraz traktowane jako określona liczba spacji (konfigurowalne za pomocą opcji -ftabstop, domyślnie 8). Do przywrócenia starego zachowania proponowana jest opcja „-fdiagnostics-column-unit=byte”, a do określenia wartości początkowej (numeracja od 0 lub 1) – opcja „-fdiagnostics-column-origin=”.
  • Wektoryzator uwzględnia całą zawartość funkcji i dodaje możliwości przetwarzania związane z przecięciami i odniesieniami do poprzednich bloków na grafie przepływu sterowania (CFG, graf przepływu sterowania).
  • Optymalizator implementuje możliwość konwertowania serii operacji warunkowych porównujących tę samą zmienną na wyrażenie przełączające. Wyrażenie przełączające można później zakodować za pomocą instrukcji testowania bitów (dodano opcję „-fbit-tests”, aby kontrolować taką konwersję).
  • Ulepszone optymalizacje międzyproceduralne. Dodano nową przepustkę IPA-modref (-fipa-modref) do śledzenia efektów ubocznych podczas wywoływania funkcji i poprawy dokładności analizy. Ulepszona implementacja przepustki IPA-ICF (-fipa-icf), która zmniejsza zużycie pamięci podczas kompilacji i zwiększa liczbę ujednoliconych funkcji, dla których łączone są identyczne bloki kodu. W przebiegu IPA-CP (Interprocedural Continuous Propation) poprawiono heurystyki predykcyjne, biorąc pod uwagę znane granice i cechy pętli.
  • W optymalizacji czasu łączenia (LTO) format kodu bajtowego jest optymalizowany w celu zmniejszenia rozmiaru i poprawy szybkości przetwarzania. Zmniejszone szczytowe zużycie pamięci w fazie wiązania.
  • W mechanizmie optymalizacyjnym bazującym na wynikach profilowania kodu (PGO - Profile-guided optymalizacji), który pozwala na generowanie bardziej optymalnego kodu na podstawie analizy cech wykonawczych, zmniejsza się rozmiar plików z danymi GCOV dzięki bardziej kompaktowemu pakowaniu zerowych liczników . Ulepszony tryb „-fprofile-values” poprzez śledzenie większej liczby parametrów w połączeniach pośrednich.
  • Implementacja standardu OpenMP 5.0 (Open Multi-Processing), który definiuje API i metody stosowania metod programowania równoległego na systemach wielordzeniowych i hybrydowych (CPU+GPU/DSP) z pamięcią współdzieloną i jednostkami wektoryzacji (SIMD), ma nieprzerwany. Dodano początkową obsługę dyrektywy allocate i możliwość używania heterogenicznych pętli w konstrukcjach OpenMP. Zaimplementowano obsługę zmiennej środowiskowej OMP_TARGET_OFFLOAD.
  • Udoskonalono implementację specyfikacji programowania równoległego OpenACC 2.6 przewidzianej dla języków C, C++ i Fortran, która definiuje narzędzia do odciążania operacji na procesorach graficznych i wyspecjalizowanych procesorach, takich jak NVIDIA PTX.
  • Dla języków C zaimplementowano nowy atrybut „no_stack_protector”, przeznaczony do oznaczania funkcji, dla których nie powinna być włączona ochrona stosu („-fstack-protector”). Rozszerzono atrybut „malloc” o obsługę identyfikacji par wywołań alokacji i zwolnienia pamięci (allocator/deallocator), który wykorzystywany jest w analizatorze statycznym do identyfikacji typowych błędów w pracy z pamięcią (wycieki pamięci, użycie po zwolnieniu, podwójne wywołania funkcji free itp.) oraz w ostrzeżeniach kompilatora „-Wmismatched-dealloc”, „-Wmismatched-new-delete” i „-Wfree-nonheap-object”, informujących o niezgodności pomiędzy operacjami zwalniania i alokacji pamięci.
  • Dodano nowe ostrzeżenia dla języka C:
    • „-Wmismatched-dealloc” (domyślnie włączone) - ostrzega o operacjach zwalniania pamięci, które korzystają ze wskaźnika, który nie jest kompatybilny z funkcjami alokacji pamięci.
    • "-Wsizeof-array-div" (włączone, gdy podano "-Wall") - Ostrzega przed dzieleniem dwóch operatorów sizeof, jeśli dzielnik nie odpowiada rozmiarowi elementu tablicy.
    • „-Wstringop-overread” (domyślnie włączone) – ostrzega przed wywołaniem funkcji string, która odczytuje dane z obszaru znajdującego się poza granicą tablicy.
    • „-Wtsan” (domyślnie włączone) — ostrzega o używaniu funkcji (takich jak std::atomic_thread_fence), które nie są obsługiwane przez ThreadSanitizer.
    • „-Warray-parametr” i „-Wvla-parametr” (włączone przy podaniu „-Wall”) - ostrzega przed nadpisywaniem funkcji z niezgodnymi deklaracjami argumentów związanych z tablicami o stałej i zmiennej długości.
    • Ostrzeżenie „-Wuninitialized” wykrywa teraz próby odczytu z niezainicjowanej, dynamicznie przydzielanej pamięci.
    • Ostrzeżenie „-Wfree-nonheap-object” rozszerza definicję przypadków, w których wywoływane są funkcje zwalniania pamięci ze wskaźnikiem, którego nie uzyskano za pomocą funkcji dynamicznej alokacji pamięci.
    • Ostrzeżenie „-Wmaybe-uninitialized” rozszerzyło wykrywanie przekazywania wskaźników na funkcje, które odwołują się do niezainicjowanych lokalizacji w pamięci.
  • Dla języka C zaimplementowano część nowych funkcjonalności opracowanych w ramach standardu C2X (udostępnianych po podaniu -std=c2x i -std=gnu2x): makra BOOL_MAX i BOOL_WIDTH, opcjonalne wskazanie nazw nieużywanych parametrów w funkcji definicje (jak w C++), atrybut „[ [nodiscard]]”, operator preprocesora „__has_c_attribute”, makra FLT_IS_IEC_60559, DBL_IS_IEC_60559, LDBL_IS_IEC_60559, __STDC_WANT_IEC_60559_EXT__, INFINITY, NAN, FLT_SNAN, DBL_SNAN, LDBL_SNAN, DEC_INFINITY i DEC_NAN, NaN=makra dla FloatN , _FloatNx i _DecimalN, możliwość określenia znaków skoku przed deklaracjami i na końcu instrukcji złożonych.
  • Dla języka C++ zaimplementowano część zmian i innowacji zaproponowanych w standardzie C++20, m.in. funkcje wirtualne „consteval virtual”, pseudodestruktory końca cyklu życia obiektów, zastosowanie klasy wyliczeniowej oraz obliczanie rozmiaru tablicy w „nowym” wyrażeniu.
  • W przypadku C++ dodano eksperymentalną obsługę niektórych ulepszeń opracowywanych dla przyszłego standardu C++23 (-std=c++23, -std=gnu++23, -std=c++2b, -std=gnu +2b). Na przykład dostępna jest teraz obsługa dosłownego sufiksu „zu” dla podpisanych wartości size_t.
  • W bibliotece libstdc++ udoskonalono obsługę standardu C++17, włączając wprowadzenie implementacji std::from_chars i std::to_chars dla typów zmiennoprzecinkowych. Zaimplementowano nowe elementy standardu C++20, m.in. std::bit_cast, std::source_location, operacje atomowe Wait and Notify, , , , , a także elementy przyszłego standardu C++23 (std::to_underlying, std::is_scoped_enum). Dodano eksperymentalną obsługę typów równoległego przetwarzania danych (SIMD, typy danych równoległych). Przyspieszono wdrożenie std::uniform_int_distribution.
  • Usunięto flagę jakości alfa z libgccjit, współdzielonej biblioteki służącej do osadzania generatora kodu w innych procesach i używania go do organizowania kompilacji JIT kodu bajtowego do kodu maszynowego. Dodano możliwość budowania libgccjit dla MinGW.
  • Dodano obsługę architektury AArch64 Armv8-R (-march=armv8-r). Dla architektur AArch64 i ARM dodano obsługę procesorów (parametry -mcpu i -mtune): Arm Cortex-A78 (cortex-a78), Arm Cortex-A78AE (cortex-a78ae), Arm Cortex-A78C (cortex-a78c) , Arm Cortex-X1 (cortex-x1), Arm Neoverse V1 (neoverse-v1) i Arm Neoverse N2 (neoverse-n2). Dodano także procesory Fujitsu A64FX (a64fx) i Arm Cortex-R82 (cortex-r82), obsługujące wyłącznie architekturę AArch64.
  • Dodano obsługę instrukcji SIMD Armv8.3-a (AArch64/AArch32), SVE (AArch64), SVE2 (AArch64) i MVE (AArch32 M-profile) SIMD do autowektoryzacji operacji wykonujących dodawanie, odejmowanie, mnożenie i warianty dodawania/odejmowania po Liczby zespolone. Dodano początkową obsługę autowektoryzacji dla ARM przy użyciu zestawu instrukcji MVE.
  • W przypadku platform ARM dostępny jest pełny zestaw funkcji C zintegrowanych z kompilatorem (Intrinsics), zastąpionych rozszerzonymi instrukcjami wektorowymi (SIMD), obejmującymi wszystkie instrukcje NEON udokumentowane w specyfikacji ACLE Q3 2020.
  • Do backendu dodano obsługę procesora graficznego gfx908 w celu generowania kodu dla procesorów graficznych AMD w oparciu o mikroarchitekturę GCN.
  • Dodano obsługę nowych procesorów i zaimplementowanych w nich nowych rozszerzeń zestawu instrukcji:
    • Intel Sapphire Rapids (-march=sapphirerapids, umożliwia obsługę instrukcji MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, SERIALIZE, PTWRITE, WAITPKG, TSXLDTRK, AMT-TILE, AMX-INT8, AMX-BF16 i AVX-VNNI.
    • Intel Alderlake (-march=alderlake, umożliwia obsługę instrukcji CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, KEYLOCKER, AVX-VNNI i HRESET).
    • Intel Rocketlake (-march=rocketlake, podobny do Rocket Lake bez obsługi SGX).
    • AMD Zen 3 (-marzec=znver3).
  • Dla systemów IA-32/x86-64 opartych na procesorach Intel dodano obsługę nowych instrukcji procesorowych TSXLDTRK, SERIALIZE, HRESET, UINTRKEYLOCKER, AMX-TILE, AMX-INT8, AMX-BF16, AVX-VNNI.
  • Dodano obsługę flag „-march=x86-64-v[234]” w celu wybrania poziomów architektury x86-64 (v2 – obejmuje rozszerzenia SSE4.2, SSSE3, POPCNT i CMPXCHG16B; v3 – AVX2 i MOVBE; v4 – AVX-512 ) .
  • Dodano obsługę systemów RISC-V z kolejnością bajtów big-endian. Dodano opcję „-misa-spec=*”, aby wybrać wersję specyfikacji architektury zestawu instrukcji RISC-V. Dodano obsługę AddressSanitizer i ochronę stosu przy użyciu tagów Canary.
  • Ciągłe doskonalenie trybu analizy statycznej „-fanalyzer”, który wykonuje wymagającą dużej ilości zasobów analizę międzyproceduralną ścieżek wykonania kodu i przepływów danych w programie. Tryb jest w stanie wykryć problemy na etapie kompilacji, takie jak podwójne wywołania funkcji free() dla jednego obszaru pamięci, wycieki deskryptorów plików, wyłuskiwanie i przekazywanie wskaźników zerowych, dostęp do zwolnionych bloków pamięci, używanie niezainicjowanych wartości itp. W nowej wersji:
    • Kod śledzenia stanu programu został całkowicie przepisany. Rozwiązano problemy ze skanowaniem bardzo dużych plików C.
    • Dodano początkową obsługę języka C++.
    • Analiza alokacji i dezalokacji pamięci została wyodrębniona ze specyficznych funkcji malloc i free i obsługuje teraz nowe/usuń i nowe[]/usuń[].
    • Dodano nowe ostrzeżenia: -Wanalyzer-shift-count-ujemna, -Wanalyzer-shift-count-overflow, -Wanalyzer-write-to-const i -Wanalyzer-write-to-string-literal.
    • Dodano nowe opcje debugowania -fdump-analyzer-json i -fno-analyzer-feasibility.
    • Zaimplementowano możliwość rozbudowy analizatora poprzez wtyczki dla GCC (przygotowano m.in. wtyczkę sprawdzającą nieprawidłowe użycie global lock (GIL) w CPythonie).

Źródło: opennet.ru

Dodaj komentarz