Po sześciu miesiącach rozwoju przedstawione wydanie projektu LLVM 10.0 — Narzędzia kompatybilne z GCC (kompilatory, optymalizatory i generatory kodu), kompilujące programy do pośredniego kodu bitowego instrukcji wirtualnych typu RISC (maszyna wirtualna niskiego poziomu z wielopoziomowym systemem optymalizacji). Wygenerowany pseudokod można przekonwertować za pomocą kompilatora JIT na instrukcje maszynowe bezpośrednio w momencie wykonywania programu.
Nowe funkcje w LLVM 10.0 obejmują obsługę koncepcji C++, nie uruchamia już Clang jako oddzielnego procesu, obsługę kontroli CFG (kontrola przepływu sterowania) dla systemu Windows oraz obsługę nowych możliwości procesora.
Dodano obsługę „koncepcja", rozszerzenie szablonu C++, które zostanie uwzględnione w następnym standardzie o nazwie kodowej C++2a (włączane za pomocą flagi -std=c++2a).
Koncepcje umożliwiają zdefiniowanie zestawu wymagań dotyczących parametrów szablonu, które w czasie kompilacji ograniczają zestaw argumentów, które można zaakceptować jako parametry szablonu. Pojęcia te można wykorzystać, aby uniknąć logicznych niespójności między właściwościami typów danych używanych w szablonie a właściwościami typu danych parametrów wejściowych.
szablon
koncepcja RównośćPorównywalna = wymaga(T a, T b) {
{ a == b } -> std::boolean;
{ a != b } -> std::boolean;
};
Domyślnie uruchamianie osobnego procesu („clang -cc1”), w którym wykonywana jest kompilacja, jest zatrzymywane. Kompilacja jest teraz wykonywana w głównym procesie i można użyć opcji „-fno-integrated-cc1”, aby przywrócić stare zachowanie.
Nowe tryby diagnostyczne:
„-Wc99-designator” i „-Wreorder-init-list” ostrzegają przed używaniem inicjatorów C99 w trybie C++ w przypadkach, gdy są one poprawne w C99, ale nie w C++ 20.
"-Wsizeof-array-div" - wychwytuje sytuacje takie jak "int arr[10]; …sizeof(arr) / sizeof(short)…” (powinno mieć wartość „sizeof(arr) / sizeof(int)”).
„-Wxor-used-as-po” - ostrzega przed użyciem konstrukcji takich jak użycie operatora „^” (xor) w operacjach, które można pomylić z potęgowaniem (2^16).
"-Wfinal-dtor-non-final-class" - ostrzega o klasach, które nie są oznaczone specyfikatorem "final", ale posiadają destruktor z atrybutem "final".
„-Wtautologiczne-bitowe-porównanie” to grupa ostrzeżeń służących do diagnozowania porównań tautologicznych pomiędzy operacją bitową a stałą oraz do identyfikowania zawsze prawdziwych porównań, w których bitowa operacja OR jest stosowana do liczby nieujemnej.
„-Wbitwise-conditional-parentheses” ostrzega przed problemami podczas mieszania operatorów logicznych AND (&) i OR (|) z operatorem warunkowym (?:).
„-Wmisleading-indentation” jest odpowiednikiem czeku o tej samej nazwie z GCC, który ostrzega o wyrażeniach z wcięciem tak, jakby były częścią bloku if/else/for/while, ale w rzeczywistości nie są uwzględnione w tym bloku .
Po podaniu „-Wextra” włączone jest sprawdzanie „-Wdeprecated-copy”, ostrzegające o użyciu konstruktorów
„przenieś” i „skopiuj” w klasach z wyraźną definicją destruktora.
Kontrole "-Wtautological-overlap-compare", "-Wsizeof-pointer-div", "-Wtautological-compare", "-Wrange-loop-analytics" zostały rozszerzone.
Sprawdzanie „-Wbitwise-op-parentheses” i „-Wological-op-parentheses” jest domyślnie wyłączone.
W kodzie C i C++ operacje arytmetyczne na wskaźnikach są dozwolone tylko na tablicach. Funkcja oczyszczania niezdefiniowanego zachowania w trybie „-fsanitize=przepełnienie wskaźnika” wychwytuje teraz takie przypadki, jak dodanie niezerowego przesunięcia do wskaźnika zerowego lub utworzenie wskaźnika zerowego podczas odejmowania liczby całkowitej od wskaźnika innego niż null.
Tryb „-fsanitize=implicit-conversion” (implicit Conversion Sanitizer) jest przystosowany do identyfikowania problemów z operacjami zwiększania i zmniejszania dla typów o rozmiarze bitowym mniejszym niż typ „int”.
Podczas wybierania docelowych architektur x86 „-march=skylake-avx512”, „-march=icelake-client”, „-march=icelake-server”, „-march=cascadelake” i „-march=cooperlake” domyślnie w formacie wektorowym kod zaprzestał korzystania z 512-bitowych rejestrów zmm, z wyjątkiem ich bezpośredniego wskazania w kodzie źródłowym. Powodem jest to, że częstotliwość procesora spada podczas wykonywania operacji 512-bitowych, co może negatywnie wpłynąć na ogólną wydajność. Aby zmienić nowe zachowanie, dostępna jest opcja „-mprefer-vector-width=512”.
Zachowanie flagi „-flax-vector-conversions” jest podobne do GCC: niejawne konwersje bitów wektorowych pomiędzy wektorami całkowitymi i zmiennoprzecinkowymi są zabronione. Aby wyeliminować to ograniczenie, proponuje się użycie flagi
„-flax-vector-conversions=all”, co jest ustawieniem domyślnym.
Ulepszona obsługa procesorów MIPS z rodziny Octeon. Dodano „octeon+” do listy prawidłowych typów procesorów.
Podczas asemblowania do kodu pośredniego WebAssembly automatycznie wywoływany jest optymalizator wasm-opt, jeśli jest dostępny w systemie.
Dla systemów opartych na architekturze RISC-V dopuszczalne jest stosowanie rejestrów przechowujących wartości zmiennoprzecinkowe w blokach warunkowych wstawek inline asemblera.
Dodano nowe flagi kompilatora: „-fgnuc-version”, aby ustawić wartość wersji dla „__GNUC__” i podobnych makr; „-fmacro-prefix-map=OLD=NEW”, aby zastąpić przedrostek katalogu STARY na NOWĄ w makrach takich jak „__FILE__”; „-fpatchable-function-entry=N[,M]”, aby wygenerować określoną liczbę instrukcji NOP przed i po punkcie wejścia funkcji. Dla RISC-V
dodano obsługę flag „-fixed-xX”, „-mcmodel=medany” i „-mcmodel=medlow”.
Dodano obsługę atrybutu „__attribute__((target(„branch-protection=…”))), którego działanie jest podobne do opcji -ochrona-gałęzi.
Na platformie Windows po podaniu flagi „-cfguard” zaimplementowano zastępowanie kontroli integralności przepływu wykonywania (Control Flow Guard) dla pośrednich wywołań funkcji. Aby wyłączyć podstawienie czeków, możesz użyć flagi „-cfguard-nochecks” lub modyfikatora „__declspec(guard(nocf))”.
Zachowanie atrybutu gnu_inline jest podobne do GCC w przypadkach, gdy jest on używany bez słowa kluczowego „extern”.
Rozszerzono możliwości związane z obsługą OpenCL i CUDA. Dodano obsługę nowych funkcji OpenMP 5.0.
Do narzędzia clang-format dodano opcję Standard, która umożliwia określenie wersji standardu C++ używanego podczas analizowania i formatowania kodu (Latest, Auto, c++03, c++11, c++14, c++17, c++20).
Do analizatora statycznego dodano nowe kontrole: alpha.cplusplus.PlacementNew w celu ustalenia, czy jest wystarczająca ilość miejsca w pamięci, fuchsia.HandleChecker w celu wykrycia wycieków związanych z procedurami obsługi Fuchsia, security.insecureAPI.decodeValueOfObjCType w celu wykrycia potencjalnego przepełnienia bufora przy użyciu [NSCoder decodeValueOfObjCType :Na:] .
Narzędzie Undefinied Behaviour Sanitizer (UBSan) rozszerzyło kontrolę przepełnienia wskaźnika, aby wychwycić zastosowanie niezerowych przesunięć do wskaźników NULL lub wynikające z tego dodanie przesunięcia wskaźnika NULL.
W linterze - schludnie dodany duża część nowych czeków.
Do ramy Atrybutor Dodano nowe optymalizacje i analizatory międzyproceduralne. Przewidywany jest stan 19 różnych atrybutów, w tym 12 atrybutów, 12 LLVM IR i 7 atrybutów abstrakcyjnych, takich jak żywotność.
Dodano nowe funkcje matematyczne macierzy wbudowane w kompilator (Istota), które podczas kompilacji są zastępowane wydajnymi instrukcjami wektorowymi.
Wprowadzono liczne ulepszenia w backendach dla architektur X86, AArch64, ARM, SystemZ, MIPS, AMDGPU i PowerPC. Dodano obsługę procesora
Cortex-A65, Cortex-A65AE, Neoverse E1 i Neoverse N1. Dla ARMv8.1-M zoptymalizowano proces generowania kodu (pojawiła się np. obsługa pętli przy minimalnym narzucie) oraz dodano obsługę autowektoryzacji za pomocą rozszerzenia MVE. Ulepszona obsługa procesora MIPS Octeon. W przypadku PowerPC włączona jest wektoryzacja podprogramów matematycznych przy użyciu biblioteki MASSV (Mathematical Acceleration SubSystem), poprawiono generowanie kodu i zoptymalizowano dostęp do pamięci z pętli. Dla x86 zmieniono obsługę typów wektorów v2i32, v4i16, v2i16, v8i8, v4i8 i v2i8.
Ulepszony generator kodu dla WebAssembly. Dodano obsługę instrukcji TLS (Thread-Local Storage) i atomic.fence. Znacząco rozszerzono obsługę SIMD. Pliki obiektów WebAssembly mają teraz możliwość używania sygnatur funkcji wielowartościowych.
Analizator jest używany podczas przetwarzania pętli PamięćSSA, co pozwala zdefiniować zależności pomiędzy różnymi operacjami na pamięci. MemorySSA może skrócić czas kompilacji i wykonania lub może być używana zamiast AliasSetTracker bez utraty wydajności.
Debuger LLDB znacznie poprawił obsługę formatu DWARF v5. Ulepszona obsługa budowania za pomocą MinGW
i dodano początkową możliwość debugowania plików wykonywalnych Windows dla architektur ARM i ARM64. Dodano opisy opcji oferowanych podczas automatycznego uzupełniania danych wejściowych po naciśnięciu klawisza Tab.
Rozszerzony Możliwości łącznika LLD. Ulepszona obsługa formatu ELF, w tym zapewnienie pełnej kompatybilności szablonów glob z linkerem GNU, dodanie obsługi skompresowanych sekcji debugowania „.zdebug”, dodanie właściwości PT_GNU_PROPERTY w celu zdefiniowania sekcji .note.gnu.property (można wykorzystać w przyszłości Jądra Linuksa),
Zaimplementowano tryby „-z noseparate-code”, „-z oddzielny kod” i „-z oddzielne-ładowalne-segmenty”. Ulepszona obsługa MinGW i WebAssembly.