Lansarea suitei de compilare LLVM 10.0

După șase luni de dezvoltare prezentat lansarea proiectului LLVM 10.0 — Instrumente compatibile cu GCC (compilatoare, optimizatoare și generatoare de cod), compilarea programelor în coduri de biți intermediare ale instrucțiunilor virtuale asemănătoare RISC (mașină virtuală de nivel scăzut cu un sistem de optimizare pe mai multe niveluri). Pseudocodul generat poate fi convertit folosind un compilator JIT în instrucțiuni de mașină direct în momentul execuției programului.

Noile funcții din LLVM 10.0 includ suport pentru conceptele C++, nu mai rulează Clang ca proces separat, suport pentru verificări CFG (control flow guard) pentru Windows și suport pentru noi capabilități CPU.

Îmbunătățiri în Clang 10.0:

  • S-a adăugat suport pentru „concepte", o extensie de șablon C++ care va fi inclusă în următorul standard, cu nume de cod C++2a (activată de indicatorul -std=c++2a).
    Conceptele vă permit să definiți un set de cerințe de parametri șablon care, în momentul compilării, limitează setul de argumente care pot fi acceptate ca parametri șablon. Conceptele pot fi folosite pentru a evita inconsecvențele logice între proprietățile tipurilor de date utilizate în șablon și proprietățile tipului de date ale parametrilor de intrare.

    șablon
    concept EqualityComparable = necesită(T a, T b) {
    { a == b } -> std::boolean;
    { a != b } -> std::boolean;
    };

  • În mod implicit, lansarea unui proces separat („clang -cc1”) în care se realizează compilarea este oprită. Compilarea se face acum în procesul principal, iar opțiunea „-fno-integrated-cc1” poate fi folosită pentru a restabili vechiul comportament.
  • Noi moduri de diagnosticare:
    • „-Wc99-designator” și „-Wreorder-init-list” avertizează împotriva utilizării inițializatoarelor C99 în modul C++ în cazurile în care acestea sunt corecte în C99, dar nu în C++20.
    • „-Wsizeof-array-div” - prinde situații precum „int arr[10]; …sizeof(arr) / sizeof(short)…” (ar trebui să fie „sizeof(arr) / sizeof(int)”).
    • „-Wxor-used-as-po” - avertizează împotriva utilizării constructelor precum utilizarea operatorului „^” (xor) în operațiuni care pot fi confundate cu exponențiația (2^16).
    • „-Wfinal-dtor-non-final-class” - avertizează despre clasele care nu sunt marcate cu specificatorul „final”, dar au un destructor cu atributul „final”.
    • „-Wtautological-bitwise-compare” este un grup de avertismente pentru diagnosticarea comparațiilor tautologice între o operație pe biți și o constantă și pentru identificarea comparațiilor întotdeauna adevărate în care operația SAU pe biți este aplicată unui număr nenegativ.
    • „-Wbitwise-conditional-parentheses” avertizează asupra problemelor la amestecarea operatorilor logici ȘI (&) și SAU (|) cu operatorul condiționat (?:).
    • „-Wmisleading-indentation” este un analog al cecului cu același nume din GCC, care avertizează despre expresiile indentate ca și cum ar fi parte dintr-un bloc if/else/for/while, dar de fapt nu sunt incluse în acest bloc .
    • Când se specifică „-Wextra”, verificarea „-Wdeprecated-copy” este activată, avertizând despre utilizarea constructorilor
      „mutare” și „copiere” în clase cu o definiție explicită a destructorului.

    • Verificările „-Wtautological-overlap-compare”, „-Wsizeof-pointer-div”, „-Wtautological-compare”, „-Wrange-loop-analysis” au fost extinse.
    • Verificările „-Wbitwise-op-parentheses” și „-Wlogical-op-parentheses” sunt dezactivate implicit.
  • În codul C și C++, operațiile aritmetice cu pointer sunt permise numai în matrice. Undefined Behavior Sanitizer în modul „-fsanitize=pointer-overflow” prinde acum cazuri precum adăugarea unui offset diferit de zero la un pointer nul sau crearea unui pointer nul atunci când scade un număr întreg dintr-un pointer non-nul.
  • Modul „-fsanitize=implicit-conversion” (Implicit Conversion Sanitizer) este adaptat pentru a identifica problemele cu operațiunile de creștere și decrementare pentru tipurile cu o dimensiune de biți mai mică decât cea a tipului „int”.
  • Când selectați arhitecturi țintă x86 „-march=skylake-avx512”, „-march=icelake-client”, „-march=icelake-server”, „-march=cascadelake” și „-march=cooperlake” implicit în formatul vectorizat codul a încetat să mai folosească registre zmm de 512 biți, cu excepția indicației lor directe în codul sursă. Motivul este că frecvența procesorului scade atunci când se efectuează operațiuni pe 512 biți, ceea ce poate afecta negativ performanța generală. Pentru a modifica noul comportament, este furnizată opțiunea „-mprefer-vector-width=512”.
  • Comportamentul indicatorului „-flax-vector-conversions” este similar cu GCC: conversiile implicite de biți vectoriali între vectori întregi și în virgulă mobilă sunt interzise. Pentru a elimina această limitare, se propune utilizarea steagului
    „-flax-vector-conversions=all” care este implicit.

  • Suport îmbunătățit pentru procesoarele MIPS din familia Octeon. S-a adăugat „octeon+” la lista de tipuri de CPU valide.
  • La asamblarea în codul intermediar WebAssembly, optimizatorul wasm-opt este apelat automat, dacă este disponibil în sistem.
  • Pentru sistemele bazate pe arhitectura RISC-V, utilizarea registrelor care stochează valori în virgulă mobilă este permisă în blocurile condiționate de inserții inline ale asamblatorului.
  • S-au adăugat noi steaguri de compilator: „-fgnuc-version” pentru a seta valoarea versiunii pentru „__GNUC__” și macrocomenzi similare; „-fmacro-prefix-map=OLD=NEW” pentru a înlocui prefixul de director OLD cu NEW în macrocomenzi precum „__FILE__”; „-fpatchable-function-entry=N[,M]” pentru a genera un anumit număr de instrucțiuni NOP înainte și după punctul de intrare al funcției. Pentru RISC-V
    a adăugat suport pentru steaguri „-ffixed-xX”, „-mcmodel=medany” și „-mcmodel=medlow”.

  • S-a adăugat suport pentru atributul „__attribute__((target(“branch-protection=...”))), al cărui efect este similar cu opțiunea -protectie-branche.
  • Pe platforma Windows, când se specifică indicatorul „-cfguard”, este implementată înlocuirea verificărilor de integritate a fluxului de execuție (Control Flow Guard) cu apelurile indirecte de funcție. Pentru a dezactiva înlocuirea cecurilor, puteți folosi indicatorul „-cfguard-nochecks” sau modificatorul „__declspec(guard(nocf))”.
  • Comportamentul atributului gnu_inline este similar cu GCC în cazurile în care este utilizat fără cuvântul cheie „extern”.
  • Capacitățile asociate cu suportul OpenCL și CUDA au fost extinse. S-a adăugat suport pentru noile funcții OpenMP 5.0.
  • O opțiune Standard a fost adăugată la utilitarul clang-format, care vă permite să determinați versiunea standardului C++ utilizată la analizarea și formatarea codului (Latest, Auto, c++03, c++11, c++14, c++17, c++20).
  • Au fost adăugate noi verificări la analizorul static: alpha.cplusplus.PlacementNew pentru a determina dacă există suficient spațiu de stocare, fuchsia.HandleChecker pentru a detecta scurgerile legate de manipulatorii Fuchsia, security.insecureAPI.decodeValueOfObjCType pentru a detecta potențialele depășiri ale buffer-ului atunci când utilizați [NSCoder decodebValueyOf :la:] .
  • Undefined Behavior Sanitizer (UBSan) și-a extins verificările de depășire a indicatorului pentru a surprinde aplicarea decalajelor non-zero la pointerii NULL sau adăugarea rezultată a unui offset de pointer NULL.
  • In linter clang-tidy adăugat o mare parte a noilor cecuri.

Principalul inovații LLVM 10.0:

  • La cadru Atributor Au fost adăugate noi optimizări interprocedurale și analizoare. Este prezisă starea a 19 atribute diferite, inclusiv 12 atribute, 12 LLVM IR și 7 atribute abstracte, cum ar fi vivacitatea.
  • S-au adăugat noi funcții matematice matrice încorporate în compilator (Intrinseci), care sunt înlocuite cu instrucțiuni vectoriale eficiente în timpul compilării.
  • Au fost aduse numeroase îmbunătățiri backend-urilor pentru arhitecturile X86, AArch64, ARM, SystemZ, MIPS, AMDGPU și PowerPC. S-a adăugat suport pentru CPU
    Cortex-A65, Cortex-A65AE, Neoverse E1 și Neoverse N1. Pentru ARMv8.1-M, ​​procesul de generare a codului a fost optimizat (de exemplu, a apărut suportul pentru bucle cu supraîncărcare minimă) și a fost adăugat suport pentru autovectorizare folosind extensia MVE. Suport îmbunătățit pentru CPU MIPS Octeon. Pentru PowerPC, vectorizarea subrutinelor matematice folosind biblioteca MASSV (Mathematical Acceleration SubSystem) este activată, generarea de cod este îmbunătățită și accesul la memorie din bucle este optimizat. Pentru x86, gestionarea tipurilor de vector v2i32, v4i16, v2i16, v8i8, v4i8 și v2i8 a fost schimbată.

  • Generator de cod îmbunătățit pentru WebAssembly. S-a adăugat suport pentru TLS (Thread-Local Storage) și instrucțiuni atomic.fence. Suportul SIMD a fost extins semnificativ. Fișierele obiect WebAssembly au acum capacitatea de a utiliza semnături de funcții cu valori multiple.
  • Analizorul este utilizat la procesarea buclelor MemorySSA, care vă permite să definiți dependențe între diferite operații de memorie. MemorySSA poate reduce timpul de compilare și execuție sau poate fi utilizat în locul AliasSetTracker fără pierderi de performanță.
  • Depanatorul LLDB are suport îmbunătățit semnificativ pentru formatul DWARF v5. Suport îmbunătățit pentru construirea cu MinGW
    și a adăugat capacitatea inițială de a depana executabile Windows pentru arhitecturile ARM și ARM64. S-au adăugat descrieri ale opțiunilor oferite la completarea automată a intrării prin apăsarea tabulatorului.

  • Extins Capabilitati de linker LLD. Suport îmbunătățit pentru formatul ELF, inclusiv asigurarea compatibilității depline a șabloanelor glob cu linkerul GNU, adăugarea suportului pentru secțiunile de depanare comprimate „.zdebug”, adăugarea proprietății PT_GNU_PROPERTY pentru a defini secțiunea .note.gnu.property (poate fi folosită în viitor nuclee Linux),
    Au fost implementate modurile „-z noseparate-code”, „-z separate-code” și „-z separate-loadable-segments”. Suport îmbunătățit pentru MinGW și WebAssembly.

Sursa: opennet.ru

Adauga un comentariu