Wydanie zestawu kompilatorów LLVM 16.0

Po sześciu miesiącach rozwoju zostaje zaprezentowane wydanie projektu LLVM 16.0 — zestawu narzędzi kompatybilnego z GCC (kompilatory, optymalizatory i generatory kodu), który kompiluje programy w pośredni kod bitowy instrukcji wirtualnych podobnych do RISC (maszyna wirtualna niskiego poziomu z wielopoziomowy system optymalizacji). Wygenerowany pseudokod może zostać przekształcony przez kompilator JIT w instrukcje maszynowe w momencie wykonywania programu.

Główne ulepszenia w Clang 16.0:

  • Domyślny standard C++/ObjC++ jest ustawiony na gnu++17 (wcześniej gnu++14), co oznacza domyślnie obsługę funkcji C++17 z rozszerzeniami GNU. Możesz użyć opcji „-std=gnu++14”, aby powrócić do poprzedniego zachowania.
  • Zaimplementowane zaawansowane funkcje związane ze standardem C++20:
    • Warunkowo trywialne specjalne funkcje składowe,
    • przechwytywanie powiązań strukturalnych w funkcjach lambda,
    • Operator równości wewnątrz wyrażeń,
    • Możliwość nie określania słowa kluczowego typename w niektórych kontekstach,
    • Dopuszczalność inicjalizacji agregatu w nawiasach („Aggr(val1, val2)”).
  • Zaimplementowane funkcje zdefiniowane w przyszłym standardzie C++2b:
    • Etykiety są dozwolone na końcu wyrażeń złożonych,
    • operator statyczny(),
    • operator statyczny [],
    • Zapewniona kompatybilność z typem char8_t,
    • Zakres znaków dozwolonych w "\N{...}" został rozszerzony,
    • Dodano możliwość używania zmiennych zadeklarowanych jako "static constexpr" w funkcjach zadeklarowanych jako constexpr.
  • Zaimplementowane funkcje zdefiniowane w przyszłym standardzie C2x C:
    • Aby wyłączyć ostrzeżenie „-Wunused-label”, można zastosować atrybut „[[maybe_unused]]” do etykiet
    • Etykiety można umieszczać w dowolnym miejscu wewnątrz wyrażeń złożonych,
    • Dodano operatory typeof i typeof_unqual,
    • Nowy typ nullptr_t i stała nullptr do definiowania wskaźników o wartości null, które można przekonwertować na dowolny typ wskaźnika, i reprezentują wariant wartości NULL, który nie jest powiązany z typami całkowitymi i wartością void*.
    • W trybie C2x dozwolone jest wywołanie makra va_start ze zmienną liczbą argumentów (variadic).
  • W trybach zgodności C99, C11 i C17 opcje „-Wimplicit-function-declaration” i „-Wimplicit-int” domyślnie generują teraz błąd zamiast ostrzeżenia.
  • Pośrednie użycie "void *" (na przykład "void func(void *p) { *p; }") w trybie C++ generuje teraz błąd, podobny do ISO C++, GCC, ICC i MSVC.
  • Określanie pól bitowych jako operandów instrukcji (np. „__asm { mov eax, s.bf }”) w blokach asemblera inline w stylu firmy Microsoft generuje teraz błąd.
  • Dodano diagnostykę obecności różnych struktur i związków o tych samych nazwach w różnych modułach.
  • Rozszerzone możliwości związane z obsługą OpenCL i OpenMP. Ulepszona diagnostyka szablonów C++ używanych w argumentach jądra OpenCL. Ulepszona obsługa bloków kolejkowania dla AMDGPU. Atrybut nounwind jest niejawnie dodawany do wszystkich funkcji. Ulepszona obsługa wbudowanych funkcji.
  • Zapewniono możliwość użycia zmiennej środowiskowej CLANG_CRASH_DIAGNOSTICS_DIR do zdefiniowania katalogu, w którym zapisywane są dane diagnostyczne awarii.
  • Obsługa Unicode została zaktualizowana do specyfikacji Unicode 15.0. Niektóre symbole matematyczne są dozwolone w identyfikatorach, takie jak „₊” (na przykład „double xₖ₊₁”).
  • Dodano obsługę ładowania wielu plików konfiguracyjnych (najpierw ładowane są domyślne pliki konfiguracyjne, a następnie te określone za pomocą flagi „--config=”, którą można teraz określić wielokrotnie). Zmieniono domyślną kolejność ładowania pliku konfiguracyjnego: clang próbuje najpierw załadować plik - .cfg i jeśli nie zostanie znaleziony, spróbuje załadować dwa pliki .cfg i cfg. Dodano flagę „--no-default-config”, aby domyślnie wyłączyć ładowanie plików konfiguracyjnych.
  • Aby zapewnić powtarzalność kompilacji, możliwe jest zastąpienie aktualnych wartości daty i czasu w makrach __DATE__, __TIME__ i __TIMESTAMP__ czasem określonym w zmiennej środowiskowej SOURCE_DATE_EPOCH.
  • Aby sprawdzić wbudowane funkcje (wbudowane), których można użyć w kontekście stałych, dodano makro „__has_constexpr_builtin”.
  • Dodano nową flagę kompilacji „-fcoro-aligned-allocation” dla wyrównanej alokacji ramek współprogramu.
  • Flaga "-fstrict-flex-arrays=" implementuje obsługę trzeciego poziomu sprawdzania elastycznego elementu tablicy w strukturach (Flexible Array Members, tablica o nieokreślonym rozmiarze na końcu struktury). Na trzecim poziomie tylko rozmiar „[]” (na przykład „int b[]”) jest traktowany jako tablica elastyczna, ale rozmiar „[0]” (na przykład „int b[0]”) nie jest.
  • Dodano flagę „-fmodule-output”, aby włączyć model kompilacji jednofazowej dla standardowych modułów C++.
  • Dodano tryb „-Rpass-analysis=stack-frame-layout”, który umożliwia diagnozowanie problemów z układem ramek stosu.
  • Dodano nowy atrybut __attribute__((target_version("cpu_features"))) oraz rozszerzono funkcjonalność atrybutu __attribute__((target_clones("cpu_features1″,"cpu_features2",…))) w celu wybrania określonych wersji dostarczonych funkcji przez procesor AArch64.
  • Udoskonalone narzędzia diagnostyczne:
    • Dodano ostrzeżenie „-Wsingle-bit-bitfield-constant-conversion”, aby wykryć niejawne obcięcie podczas przypisywania jednego do jednobitowego pola bitowego ze znakiem.
    • Rozszerzona diagnostyka niezainicjowanych zmiennych constexpr.
    • Dodano ostrzeżenia „-Wcast-function-type-strict” i „-Win Compatible-function-pointer-types-strict” w celu wykrycia potencjalnych problemów z rzutowaniem typów funkcji.
    • Dodano diagnostykę używania nieprawidłowych lub zarezerwowanych nazw modułów w blokach eksportu.
    • Poprawione wykrywanie brakujących słów kluczowych „auto” w definicjach.
    • Dodano sprawdzanie dodatkowych sytuacji przepełnienia do implementacji ostrzeżenia „-Winteger-overflow”.
  • Zaimplementowano obsługę architektury zestawu instrukcji LoongArch (-march=loongarch64 lub -march=la464) używanej w procesorach Loongson 3 5000, która implementuje nowy RISC ISA podobny do MIPS i RISC-V.

Kluczowe innowacje w LLVM 16.0:

  • W kodzie LLVM dozwolone jest stosowanie elementów zdefiniowanych w standardzie C++17.
  • Zwiększone wymagania środowiskowe dla budowania LLVM. Zestaw narzędzi do budowania powinien teraz obsługiwać standard C++ 17, tj. kompilacja wymaga co najmniej GCC 7.1, Clang 5.0, Apple Clang 10.0 lub Visual Studio 2019 16.7.
  • Do backendu AArch64 dodano obsługę procesorów Cortex-A715, Cortex-X3 i Neoverse V2, asemblera RME MEC (Memory Encryption Contexts), rozszerzeń Armv8.3 (Complex Number) i Function Multi Versioning.
  • Backend architektury ARM nie obsługuje już platform docelowych Armv2, Armv2A, Armv3 i Armv3M, dla których nie było zagwarantowane poprawne generowanie kodu. Dodano możliwość generowania kodu instrukcji do pracy z liczbami zespolonymi.
  • Dodano obsługę architektur zestawu instrukcji (ISA) AMX-FP86, CMPCXADD, AVX-IFMA, AVX-VNNI-INT16, AVX-NE-CONVERT do zaplecza X8. Dodano obsługę instrukcji RDMSRLIST, RMSRLIST i WRMSRNS. Zaimplementowano opcje "-mcpu=raptorlake", "-mcpu=meteorlake", "-mcpu=emeraldrapids", "-mcpu=sierraforest", "-mcpu=graniterapids" i "-mcpu=grandridge".
  • Dodano oficjalne wsparcie dla platformy LoongArch.
  • Ulepszone backendy dla architektur MIPS, PowerPC i RISC-V
  • Do debugera LLDB dodano obsługę debugowania 64-bitowych plików wykonywalnych dla architektury LoongArch. Poprawiona obsługa symboli debugowania COFF. Dodano filtrowanie zduplikowanych bibliotek DLL na liście załadowanych modułów systemu Windows.
  • W bibliotece Libc++ główne prace koncentrowały się na implementacji obsługi nowych funkcji standardów C++20 i C++23.
  • Czas łączenia został znacznie skrócony w konsolidatorze LDD dzięki zrównolegleniu skanowania relokacji adresów i operacji inicjalizacji sekcji. Dodano obsługę kompresji sekcji przy użyciu algorytmu ZSTD.

Źródło: opennet.ru

Dodaj komentarz