有人可以帮我理解一些较新的编译器技术之间的关系吗?究竟什么是LLVM和clang,它们与gcc / g ++有什么关系?
答案 0 :(得分:48)
所以一个典型的流程是:C代码---> GCC的C前端---> RTL ---> GCC的x86后端---> x86机器代码。
GCC支持几个前端:C,C ++,Java,Objective C,Go和Fortran。
GCC支持多种后端:32位x86,64位x86,小端ARM,大端ARM,MIPS,SPARC,PowerPC等。
Frontends将文本转换为RTL,后端将RTL转换为某种机器代码。
LLVM是一种中间层机器无关的计算表示,在概念上类似于GCC的RTL。它是自己的类型系统和指令集,中间形式(IF)。如果我理解正确的话,LLVM的IF比GCC的RTL更丰富,更具表现力,更灵活,它有很多好处。用于许多不同语言的LLVM的编译器前端都可以编译为LLVM IF。这可以用于“传统”语言,如C,C ++,Java等,但它也可以用于“非常规”编程任务,如GPU着色器。
LLVM可能是两件事。 LLVM-the-machine,它是类型系统和指令集,可能更好地称为“LLVM IF”;和LLVM-the-API,它是用于操作LLVM IF中的代码的软件,例如LLVM JIT编译器,或者LLVM x86机器代码后端。
Clang是处理C系列语言的LLVM的前端:C,C ++,Objective C,Objective C ++。 Clang将C / C ++ / etc转换为LLVM IF,LLVM对IF执行优化,LLVM x86后端写出x86机器代码以供执行。
尽管名称不同,但LLVM并不是传统意义上的虚拟机 - 它是一种计算模型和表示,非常适合操作代码的任务。
LLVMs的流行来自于它是一个完全具体的编译器API。它可用于对代码执行静态分析(“这段代码是否会意外地使用未初始化的内存?”),优化,代码解析(例如构建IDE)。 GCC的内部结构非常高,因此以这种方式使用GCC非常困难。一个例子是GCC的前端在解析期间执行一些优化,因此不可能总是得到代码类型的完美表示,例如,报告错误和执行波浪线语法突出显示,因为某些信息可能已经丢失。
据我了解,Clang保留了未经优化的解析语法,使第三方工具可以使用其输出并将转换等同于原始文本,最值得注意的是,Clang的错误消息更有帮助,因为它们可以突出显示这条线的确切部分。