Кіріспе

Көптеген бағдарламалау тілдері үшін компилятордың артқы бөлігі (бэкенді)

LLVM – кез келген бағдарламалау тілі үшін фронтэнд және кез келген нұсқаулар жиынтығы архитектурасы үшін бэкенд әзірлеуге арналған компилятор және құралдар жиынтығының технологиялар жиынтығы. LLVM тілге тәуелсіз аралық өрнеуге (IR) негізделген, ол портативті, жоғары деңгейдегі ассемблер тілі ретінде қызмет етеді және бірнеше өтулерде әртүрлі түрлендірулермен оңтайландырылуы мүмкін. LLVM атауы бастапқыда «Төменгі деңгейлі виртуалды машина» дегенді білдірген, бірақ жоба кеңейді және атауы енді ресми түрде аббревиатура емес. LLVM C++ тілінде жазылған және компиляция уақытында, байланыс уақытында, орындалу уақытында және «бос уақытта» оңтайландыру үшін жасалған. Алғашында C және C++ үшін іске асырылған LLVM-нің тілге бейтарап дизайны содан бері көптеген фронтэндтерді тудырды: LLVM-ді пайдаланатын компиляторлары бар тілдер (немесе тікелей LLVM-ді пайдаланбайтын, бірақ LLVM IR ретінде компиляцияланған бағдарламаларды жасай алатын) ActionScript, Ada, C# for NET, Common Lisp, PicoLisp, Crystal, CUDA, D, Delphi, Dylan, Forth, Fortran, FreeBASIC, Free Pascal, Halide, Haskell, Java bytecode, Julia, Kotlin, LabVIEW-тің G тілі, Lua, Objective C, OpenCL, PostgreSQL-дің SQL және PLpgSQL, Ruby, Rust, Scala, Swift, Xojo және Zig.

Тарих

LLVM жобасы 2000 жылы Викрам Адве мен Крис Латтнердің басшылығымен Иллинойс университетінің Урбана-Шампейн қаласындағы бөлімшесінде басталды. LLVM бастапқыда статикалық және динамикалық бағдарламалау тілдері үшін динамикалық компиляция техникаларын зерттеуге арналған ғылыми-зерттеу инфрақұрылымы ретінде әзірленді. LLVM Иллинойс университеті/NCSA ашық лицензиясы бойынша жарияланды және 2011 жылғы Xcode 4 нұсқасынан бастап macOS және iOS үшін Apple Xcode әзірлеу құралдарының маңызды бөлігіне айналды. 2006 жылы Латтнер Clang деп аталатын жаңа жобада жұмыс істей бастады. Clang фронтенді және LLVM бэкендінің үйлесімі Clang/LLVM немесе жай ғана Clang деп аталады. LLVM атауы бастапқыда «Төмен деңгейлі виртуалды машина» деген сөздердің бас әріптерінен құралған болатын. Алайда, LLVM жобасы қазіргі көптеген дамытушылардың виртуалды машина деп есептейтін нәрседен мүлдем басқаша бағытқа қадам басты. Бұл бас әріптерін «шатастыратын» және «жеткіліксіз» етті, сондықтан 2011 жылдан бастап LLVM «ресми түрде аббревиатура емес», ал LLVM жобасын білдіретін бренд ретінде танылды. Жобаға LLVM аралық өрнегі (IR), LLVM отладчик, C++ стандартты кітапханасының LLVM нұсқасы (C++11 және C++14 толық қолдауымен) және тағы да басқалары кіреді. LLVM-ді LLVM қоры басқарады. Компилятор инженері Таня Латтнер 2014 жылы президент болып тағайындалды және 2024 жылға дейін қызмет етіп келеді. «LLVM-ді жобалау және іске асыруы үшін» Компьютерлік машиналар қауымдастығы 2012 жылғы ACM бағдарламалық жүйе сыйлығын Викрам Адве, Крис Латтнер және Эван Ченгке табыс етті. Жоба бастапқыда UIUC лицензиясымен қолжетімді болды. 2019 жылы шыққан v9.0.0 нұсқасынан кейін LLVM Apache License 2.0 лицензиясына LLVM ерекшеліктерімен қайта лицензияланды.

Ерекшеліктері

LLVM толық компилятор жүйесінің ортаңғы қабаттарын қамтамасыз ете алады, компилятордан аралық өрнек (IR) кодын қабылдап, оңтайландырылған IR шығарады. Бұл жаңа IR кейін мақсатты платформа үшін машинаға тәуелді ассемблер тілі кодына түрлендіріліп, байланыстырылуы мүмкін. LLVM GNU Compiler Collection (GCC) құралдар жиынтығынан IR-ді қабылдай алады, бұл сол жоба үшін жазылған көптеген компилятордың алдыңғы бөліктерімен пайдалануға мүмкіндік береді. LLVM-ді gcc-мен 7.5 нұсқасынан кейін де құрастыруға болады. LLVM сондай-ақ компиляция кезінде, байланыстыру кезінде немесе тіпті орындалу кезінде көшірілетін машина кодын немесе екілік машина кодын да шығара алады. LLVM тілге тәуелсіз нұсқаулар жиынтығы мен типтік жүйені қолдайды. OpenGL стекіндегі графикалық код аралық өрнекте қалдырылып, мақсатты машинада орындалған кезде компиляцияланады. Жоғары деңгейдегі графикалық процессорлары (GPU) бар жүйелерде алынған код өте жұқа болып қалады, нұсқаулар минималды өзгерістермен GPU-ға жіберіледі. Төменгі деңгейдегі GPU-лары бар жүйелерде LLVM жергілікті орталық процессорда (CPU) орындалатын, GPU ішкі түрде орындай алмайтын нұсқауларды эмуляциялайтын қосымша процедураларды құрастырады. LLVM Intel GMA чипсеттерін қолданатын төменгі деңгейдегі машиналарда өнімділікті жақсартты. Ұқсас жүйе Gallium3D LLVMpipe аясында әзірленді және GNOME қабығына енгізіліп, тиісті 3D аппараттық драйвері жүктелмеген кезде жұмыс істеуге мүмкіндік берді. 2011 жылы GCC құрастырған бағдарламалар LLVM бағдарламаларынан орташа есеппен 10% артық өнімділік көрсетті. 2013 жылы phoronix LLVM GCC-ге шамалас, шамамен бірдей өнімділіктегі бинарлық файлдарды құрастырып, жеткенін хабарлады.

Құралымдары

LLVM көптеген компоненттерді біріктіретін үлкен жобаға айналды.

Алдыңғы жақтары

LLVM бастапқыда GCC стекіндегі қолданыстағы код генераторының орнын басу үшін жазылған, және GCC фронтендтерінің көптегені онымен жұмыс істеуге сәйкес келтірілді, нәтижесінде қазір қолданыстан шыққан LLVM GCC жиынтығы пайда болды. Өзгерістер әдетте LLVM IR-ге GIMPLE-ді түрлендіруді қамтиды, соның арқасында LLVM оптимизаторлары мен кодты генерациялау құралдарын GCC-нің GIMPLE жүйесі орнына пайдалануға болады. Apple компаниясы Xcode 4.x (2013) нұсқасында LLVM GCC-нің маңызды қолданушысы болды. GCC фронтендін пайдалану көбінесе уақытша шара ретінде қарастырылды, бірақ Clang-тың пайда болуымен және LLVM мен Clang-тың қазіргі заманғы және модулдік код базасының (сондай-ақ компиляция жылдамдығының) артықшылықтарымен байланысты, ол көбінесе ескірді. Қазіргі уақытта LLVM Ada, C, C++, D, Delphi, Fortran, Haskell, Julia, Objective C, Rust және Swift тілдерін әртүрлі фронтендтерді қолдана отырып компиляциялауды қолдайды. LLVM-ға кеңінен қызығушылық танылғандықтан, көптеген тілдер үшін жаңа фронтендтерді әзірлеуге бірнеше күш-жігер жұмсалды. Ең көп назар аударған – C, C++ және Objective C тілдерін қолдайтын Clang жаңа компиляторы. Көбінесе Apple компаниясының қолдауымен, Clang GCC жүйесіндегі C/Objective C компиляторын интеграцияланған даму орталарымен (IDE) оңай интеграцияланатын және көп жіптілікке кеңірек қолдау көрсететін жүйемен алмастыруға бағытталған. OpenMP директиваларына қолдау Clang-тың 3.8 нұсқасынан бастап енгізілді. Utrecht Haskell компиляторы LLVM үшін кодты генерациялай алады. Генератор дамудың бастапқы кезеңдерінде болғанымен, көптеген жағдайларда ол C кодты генерациялаудан тиімдірек болды. Glasgow Haskell Compiler (GHC) бэкенді LLVM-ды пайдаланады және GHC немесе C кодты генерациялау арқылы компиляциялауға қарағанда компиляцияланған кодты 30%-ға жылдамдатады, GHC іске асырған көптеген оптимизациялау техникаларының біреуін ғана қалып қояды. Басқа көптеген компоненттер әртүрлі даму сатыларында, оның ішінде, бірақ олармен шектелмейді, Rust компиляторы, Java байт-кодының фронтенді, Common Intermediate Language (CIL) фронтенді, Ruby 1.9-дың MacRuby нұсқасы, Standard ML үшін әртүрлі фронтендтер және жаңа графты бояу тізілімді бөлуші.

Арқалық

16-шы нұсқада LLVM көптеген нұсқаулар жиынтығын қолдайды, соның ішінде IA 32, x86 64, ARM, Qualcomm Hexagon, LoongArch, M68K, MIPS, NVIDIA Parallel Thread Execution (PTX, LLVM құжаттамасында NVPTX деп аталады), PowerPC, AMD TeraScale, соңғы AMD GPU-лары (LLVM құжаттамасында AMDGPU деп аталады), SPARC, z/Architecture (LLVM құжаттамасында SystemZ деп аталады) және XCore. Кейбір мүмкіндіктер кейбір платформаларда қолжетімді емес. IA 32, x86 64, z/Architecture, ARM және PowerPC үшін көптеген мүмкіндіктер бар. RISC V 7-ші нұсқадан бастап қолдау көрсетіледі. Бұрын LLVM басқа да артқы соңдауларды (backends), толық немесе ішінара, қолдады, олардың ішінде C артқы соңдауы, Cell SPU, mblaze (MicroBlaze), AMD R600, DEC/Compaq Alpha (Alpha AXP) және Nios2 кіретін еді, бірақ бұл аппараттық құралдардың көпшілігі ескірген, ал LLVM әзірлеушілері қолдау және техникалық қызмет көрсетуге кететін шығындар енді ақталмайды деп шешті. LLVM WebAssembly-ді де мақсат ретінде қолдайды, бұл компиляцияланған бағдарламалардың Google Chrome / Chromium, Firefox, Microsoft Edge, Apple Safari немесе WAVM сияқты WebAssembly қолдауын көрсететін ортада орындалуына мүмкіндік береді. LLVM-мен үйлесімді WebAssembly компиляторлары әдетте C, C++, D, Rust, Nim, Kotlin және басқа да бірнеше тілдерде жазылған, көбінесе өзгертілмеген бастапқы кодты қолдайды. LLVM машиналық код (MC) кіші жобасы – LLVM-нің машиналық нұсқауларды мәтіндік форматтар мен машиналық код арасында аудару үшін жасалған құралы. Бұрын LLVM машиналық кодты құрастыру үшін жүйелік құрастырушыға немесе құралдар жинағымен (toolchain) берілген құрастырушыға сүйенген. LLVM MC-нің біріктірілген құрастырушысы LLVM-нің көптеген мақсаттарын қолдайды, соның ішінде IA 32, x86 64, ARM және ARM64. Кейбір мақсаттар үшін, соның ішінде әртүрлі MIPS нұсқаулар жиынтықтары үшін, біріктірілген құрастыру қолдауы қолданылуы мүмкін, бірақ ол әлі де бета нұсқасында.

Тіркегіш

LLD кіші жобасы LLVM үшін платформаға тәуелсіз байланыстырушы құруға бағытталған. Оның мақсаты – үшінші тараптың байланыстырушысына тәуелділікті жою. 2017 жылғы мәліметтер бойынша, lld ELF, PE/COFF, Mach-O және WebAssembly форматтарын толықтығы азаятын ретпен қолдайды. Lld, GNU ld-нің екі нұсқасынан да жылдам жұмыс істейді. GNU байланыстырушылардан айырмашылығы, lld байланыстыру кезіндегі оңтайландыруды (LTO) ендірілген күйде қолдайды. Бұл кодты жылдам генерациялауға мүмкіндік береді, себебі ол байланыстыру плагинін пайдалануды қажет етпейді, бірақ LTO-ның басқа нұсқаларымен үйлесімділікті шектейді.

C++ стандартты кітапханасы

LLVM жобасы MIT лицензиясы және UIUC лицензиясы бойынша қос лицензияланған libc++ деп аталатын C++ стандартты кітапханасының іске асырылуын қамтиды. 9.0.0 нұсқасынан бастап, ол LLVM ерекшеліктерімен Apache License 2.0 лицензиясына қайта лицензияланды.

C Стандартты кітапхана

llvm libc – LLVM жобасы үшін жасалған және LLVM жобасының қажеттіліктерін ескере отырып дамытылып жатқан, толық емес, әзірге шықпаған, ABI тәуелсіз C стандартты кітапханасы.