The Architecture of Open Source Applications -- llvm

         本文阐述在形成LLVM的过程中所做的一些设计决策, LLVM是一个基金项目,用来解决和开发一套紧密的底层工具链组件(比如:汇编器,编译器,调试器等等),它被设计成可以兼容Unix系统上的现有工具,'LLVM'一度是一个缩略语,现在仅仅是此基金项目的代名词。LLVM提供了一些独特的能力,以一些伟大工具著称(比如:clang编译器,一个C/C++/Objective-C编译器,提供了一些优于GCC编译器的特性), 但LLVM区别于其他编译器的主要特点在于它内部的架构。

         LLVM项目始于2000年12月,被设计成一组可以重用的有良好接口定义的库,当时,开源程序语言的实现被设计成特别目的的工具,通常是一个单一的执行程序。例如,重用静态编译器(比如GCC)的解析器做一些静态分析或重构的工作是非常困难的。而脚本语言通常提供一种方法嵌入他们的实时运行或者解释器到大型应用中,这种实时是一个单一的代码快被包含或者排除。没有办法去重用,而且不同语言实现项目之间很少有共享。

          除了编译器自身的组合特性(composition?),流行语言实现的团体通常严重的两极分化:实现通常提供像GCC、Free Pascal、FreeBasic的静态编译器或者提供解释器、JIT的实时编译器。很难能见到同时支持上两种的语言实现,即使同时支持,通常也很少共享代码。

          在过去10年里,LLVM相当多的改变了这种状况。 LLVM现在作为一个通用框架用来实现很多不同的静态和动态编译语言(例如,GCC、JAVA、.NET、Python、Ruby、Scheme、Haskell,D支持的语言族,以及很多不计其数不为人知的语言)。它同样淘汰了一大批特殊用途的编译器,例如Apple的OpenGL栈中的实时规范引擎,Adobe的After Effects产品中的图像处理库。最后,LLVM也用于建立一大批新的产品,可能最有名的是OpenCL GPU的编程语言和实时库。

11.1 经典编译器设计的快速简介
         传统静态编译器(像大多数的C编译器)最流行的设计是三段式设计,主要部分包括前端、优化器、后端(如图11.1)。前端用于解析源代码,错误检查,生成一个特定语言的抽象语法树来表示输入码。 AST可以随意(optionally)转化为一种新的表示用于优化, 而优化器和后端在代码上执行。

         优化器负责各种各样的转换来尝试提高执行效率,如消除冗余计算,通常或多或少的独立于语言和目标机。 后端(又叫代码生成器)把代码映射成目标指令集。除了生成正确的代码,它还负责生成好的代码以利用支持目的机架构的不寻常特性。 编译器后端的通用部分包括指令集的选择,寄存器的分配,以及指令调度。
          这个模型很好的应用在解释器和JIT编译器。JVM是这个模型的一个实现,它是java byetecode作为前端和优化器间的接口。
 11.1.1 设计的暗示
         当编译器决定支持多种源码语言或者多个目的架构时,这种经典设计的最重要的优势就体现出来了, 如果编译器在优化器中使用通用代码表示,前端可以为任何可以编译成这种中间形式的语言服务,后端可以为任何目的机服务,目的机来自从中间形式编译。如图11.2。

         使用这种设计,移植这种编译器使其支持一种新的语言(例如,Algol或者BASIC),只需要实现一个新的前端, 而已经存在的优化器和后端可以重用。 如果这些部分没有分离,实现一种新的语言需要从头开始,支持N种目的机和M种语言需要N*M个编译器。
         三段式设计(which follows directly from retargetability)的另一个优点是,相较于只支持一种语言和一种目的机,此种编译器可以服务一大批程序员。对于一个开源项目,意味着会有一大批社区的潜在贡献者,很自然的增强和改进已有的编译器。这就是为什么开源编译器服务于很多社区(比如GCC),生成好的优化机器码,而闭源编译器(比如FreePASCASL)不能的原因。专有编译器情况则不同, 它的质量与项目的经费直接相关。例如,Intel ICC编译器已它生成的代码质量闻名,即使只有服务于很少一部分人。  
        三段式设计最后一个优势是实现一个前端使用的技术不同于实现优化器和后端,把这些部分独立,对个性化前端来说,使得增强和维护编译器的各个部分更容易。虽然这是个社会问题而不是技术问题,在实践中确实非常要紧的,特别是对于开源项目需要尽可能低的消除相互贡献的障碍。

11.2   现有语言的实现
        虽然三段式设计的优点在编译器教材中有有完整的描述(compelling and well-documented),实际上从来都没有完全的实现过。在LLVM没有出现前,浏览开源语言的实现,你会发现Perl,Python,Ruby,Java的实现没有共享任何代码。并且,像Glasgow Haskell Compiler(GHC)和FreeBASIC这样的项目可重定向(retargetable)到多个不同的CPU,但他们的实现只特定于他们支持的单一语言。还有各种各样的特定目的的编译器技术配置到JIT编译器中,用于图像处理、正则表达式、图形卡驱动及其它需要高效使用CPU的子领域中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值