热门问题
时间线
聊天
视角

LLVM

多种编程语言的编译器后端 来自维基百科,自由的百科全书

LLVM
Remove ads

LLVM是一套编译器基础设施项目,为自由软件,以C++寫成,包含一系列模块化的编译器组件和工具链,用来开发编译器前端后端。任意一種程式語言通過它實作出來的編譯器,都能利用上它在編譯時期鏈結時期執行時期以及“閒置時期”进行的最佳化。

事实速览 原作者, 開發者 ...

它最早以C/C++為實作對象,而目前它已支援包括ActionScriptAdaD語言FortranGLSLHaskellJava字节码Objective-CSwiftPythonRubyCrystalRustScala[2]Standard ML[3]以及C#[4]等语言。

Remove ads

历史

LLVM專案的發展起源於2000年伊利诺伊大学厄巴纳-香槟分校維克拉姆·艾夫(Vikram Adve)與克里斯·拉特納(Chris Lattner)的研究,他們想要為所有靜態及動態語言創造出動態的編譯技術。LLVM是以BSD授權來發展的开源軟體。2005年,蘋果電腦雇用了克里斯·拉特納及他的團隊為蘋果電腦開發應用程式系統[5],LLVM為現今macOSiOS開發工具的一部分。

LLVM的命名最早源自於底層虛擬機器Low Level Virtual Machine)的首字母縮寫[6],由於這個專案的範圍並不侷限於建立一個虛擬機器,這個縮寫導致了廣泛的疑惑。LLVM開始成長之後,成為眾多編譯工具及低階工具技術的統稱,使得這個名字變得更不貼切,開發者因而決定放棄這個縮寫的意涵[7],現今LLVM已單純成為一個系統,適用於LLVM下的所有專案,包含LLVM中間表示(LLVM IR)、LLVM除錯工具、LLVM C++標準函式庫等。

因LLVM對產業的貢獻,计算机协会於2012年将ACM软件系统奖授與維克拉姆·艾夫克里斯·拉特納和Evan Cheng[8]

自9.0.0版本开始,LLVM使用带有LLVM额外条款的Apache许可证2.0进行授权[9]。而从2019年10月开始,LLVM项目的代码托管正式迁移到了GitHub[10]

Remove ads

描述

LLVM提供了一套适合编译器系统的中间表示Intermediate Representation,IR),有大量变换和优化都围绕其实现。经过变换和优化后的中间语言,可以转换为目标平台相关的汇编语言代码。LLVM可以和GCC工具链一起工作,允许它与为该项目编写的大量现有编译器一起使用。

LLVM还可以在编译、链接时生成可重定位代碼英语Relocation (computing)(Relocatable Code),甚至在运行时生成二进制机器码。

LLVM支援與語言無關的指令集架構類型系統[11]。每個指令都處在静态单赋值形式(SSA)下代表著,每個變數(被稱為具有型別的暫存器)僅被賦值一次,這簡化了變數間相依性的分析。LLVM允許程式碼遵循傳統GCC系統的方式而被靜態的編譯,或者以類似JAVA等後期編譯的方式,通過即時編譯(JIT)將IF編譯成機器碼。

LLVM的型別系統包含基本型別(整數或是浮点数)及五個複合型別指標陣列向量結構函數),具體語言的型別,可以在LLVM中用基本型別的组合來表示,舉例來說,C++所使用的,可以被表示為結構函數函数指针的陣列的混合。

LLVM JIT編譯器可以最佳化程式在執行期之時去除所不需要的靜態分支,這在一些部份求值(Partial Evaluation)的案例中相當有效,即當程式有許多選項,而在特定環境下其中多數可被判斷為是不需要的。這個特色被使用在Mac OS X Leopard(v10.5)底下OpenGL的管線,當硬體不支援某個功能時依然可以被成功地運作[12]

OpenGL堆栈下的繪圖程式被編譯為中间表示,接著在機器上執行時被編譯,當系統擁有高階GPU時,這段程式會進行極少的修改並將傳遞指令給GPU,當系統擁有低階的GPU時,LLVM將會編譯更多的程序,使這段GPU無法執行的指令在本地端的中央处理器執行。LLVM增進了使用Intel GMA晶片等低端機器的效能。一個類似的系統發展於Gallium3D LLVMpipe,它已被合併到GNOME,使其可運行在沒有GPU的環境[13]

根據2011年的一项測試,GCC在執行時期的性能平均比LLVM高10%[14][15]。而2013年測試显示,LLVM可以編譯出接近GCC相同效能的執行碼[16]

Remove ads

组件

LLVM已经成为多个编译器和代码生成相关子项目的母项目。

前端

LLVM最初被用來取代GCC中的程式碼產生器[17],許多GCC的前端已經可以與其運行,LLVM目前支援AdaC语言C++D語言FortranHaskellJuliaObjective-CRustSwift的編譯,它使用許多的編譯器,有些來自4.0.1及4.2的GCC

LLVM引發一些人來為許多語言開發新的編譯器,其中一個最引發注意的就是Clang,它是一個新的編譯器,同時支援C、Objective-C以及C++。主要來自蘋果電腦的支持,Clang的目的用以取代GCC系統底下的C/Objective-C編譯器,在當代的系統,他較為容易與集成开发环境(IDE)整合,而且對於线程有更好的支援。Clang从3.8版本开始已经支持OpenMP[18]。GCC底下Objective-C的開發已經停滯,而蘋果電腦已經將其支援移至其他的維護分支。

Utrecht Haskell編譯器可以產生LLVM使用的程式碼,但它還在初期的開發階段,並且在許多案例,展示他比起C程式碼產生器擁有更好的效率[19] Glasgow Haskell Compiler(GHC)擁有一個可以運作的LLVM後端,程式執行效能對比起原先的編譯器可以達到30%的加速,它僅比一個由GHC所實現,並擁有多項最佳化技術的編譯器還慢[20]

還有其他的元件在不同的開發階段,包含(但不限於)Java字节码[21]通用中间语言(CIL)、MacRuby英语MacRuby(Ruby 1.9實現)、Standard ML及新的图着色寄存器分配器[22]

Remove ads

中间表示

LLVM的核心是中间表示(Intermediate Representation,IR),一种类似汇编的底层语言。IR是一种强类型精简指令集(RISC),并对目标指令集进行了抽象。例如,目标指令集的函数调用惯例被抽象为callret指令加上明确的参数。另外,IR采用无限个数的暂存器,使用如%0%1等形式表达。LLVM支持三种表达形式:人类可读的汇编格式,适合前端的在内存中的格式和用作序列化的紧密bitcode格式。

例如,一个简单的Hello World程序可以表达为如下的汇编形式。对IR语言的完整描述请参考LLVM官方文档[23]

@.str = internal constant [14 x i8] c"hello, world\0A\00"

declare i32 @printf(i8*, ...)

define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
    %tmp1 = getelementptr [14 x i8], [14 x i8]* @.str, i32 0, i32 0
    %tmp2 = call i32 (i8*, ...) @printf( i8* %tmp1 ) nounwind
    ret i32 0
}

LLVM计划还介入了另一种类型的中间表示名为MLIR英语MLIR (software)[24],它通过采用叫做“方言”的插件架构来帮助建造可重用且可扩展的编译器下部构造[25]

Remove ads

后端

截至版本16,LLVM已经支持多种后端指令集,包括IA-32x86-64ARMQualcomm Hexagon英语Qualcomm HexagonLoongArchM68KMIPSNvidia PTX英语Parallel Thread Execution(在LLVM文档中也称为NVPTX)、PowerPCAMD TeraScale英语TeraScale (microarchitecture)[26]、新近的AMD GPU(在LLVM文档中也叫做AMDGPU)、SPARCSystemZRISC-Vz/Architecture英语z/ArchitectureXCore英语XMOS

LLVM还支持WebAssembly为其目标,使得编译后的程序可以在启用WebAssembly的环境中运行,比如Google Chrome/ChromiumFirefoxMicrosoft EdgeApple Safari或WAVM虚拟机[27]。合规于LLVM的WebAssembly编译器,典型的支持多种语言的几乎不需修改的源代码,包括:C、C++、D、Rust、Nim、Kotlin和其它一些语言。

LLVM包含一个专门的MC模块,将机器指令在文字形式和机器码形式间相互转换。在之前LLVM依靠系统或是平台专门的工具链将汇编翻译为机器码。LLVM机器码的集成汇编器已经支持绝大多数LLVM的目标平台。

Remove ads

链接器

lld链接器子项目旨在为LLVM开发一个内置的,平台独立的链接器[28],去除对所有第三方链接器的依赖。在2017年5月,lld已经支持ELFPE/COFFMach-OWebAssembly。在lld支持不完全的情况下,用户可以使用其他项目,如GNU ld链接器。 lld支持链接时优化。当LLVM链接时优化被启用时,LLVM可以输出bitcode而不是本机代码,而本机代码生成由链接器优化处理。

C++标准库

LLVM项目包含一个C++标准库的实现(libcxx),具有MIT许可证UIUC许可证英语University of Illinois/NCSA Open Source License的双许可协议。[29]

另見

參考文獻

外部連結

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads