第1章:玩转LLVM

本文介绍了LLVM编译器基础设施,包括其起源、模块化设计、LLVMIR的作用,以及关键工具如opt、代码生成器和LLVMIR的使用。重点讲解了模块化设计在LLVM优化器中的应用和LLVMIR的通用性和结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LLVM编译器基础设施项目始于2000年伊利诺伊大学,最初是一个研究项目,旨在为各种静态和动态编程语言提供基于SSA(静态单赋值)的现代编译技术。如今,它已发展成为一个包含许多子项目的综合项目,提供一系列具有明确定义接口的可重用库。

LLVM是用C++实现的,其核心是它提供的LLVM核心库。这些库为我们提供了opt工具,即目标独立的优化器,以及对各种目标架构的代码生成支持。还有其他一些工具使用核心库,但本书的主要焦点将与上述三个相关。这些工具是围绕LLVM中间表示(LLVM IR)构建的,几乎可以映射所有高级语言。因此,基本上,要使用LLVM的优化器和代码生成技术为某种编程语言编写的代码,我们所需要做的就是为该语言编写一个前端,将高级语言转换为LLVM IR。已经有许多针对C、C++、Go、Python等语言的前端。本章将涵盖以下主题:

  • 模块化设计和库的集合
  • 熟悉LLVM IR
  • LLVM工具及其在命令行的使用

模块化设计和库的集合


LLVM最重要的特点是它被设计成一系列的库。让我们通过LLVM优化器opt的例子来理解这一点。优化器可以运行许多不同的优化过程。每个过程都写成了一个从LLVM的Pass类派生的C++类。每个写好的过程都可以编译成一个**.o文件,然后被存档成一个.a**库。这个库将包含opt工具的所有过程。库中的所有过程都是松散耦合的,即它们明确地指明了对其他过程的依赖。

当优化器运行时,LLVM的PassManager使用明确提及的依赖信息以最优方式运行过程。基于库的设计允许实现者选择执行过程的顺序,也可以根据需求选择要执行的过程。只有需要的过程才会链接到最终应用程序,而不是整个优化器。

下图展示了如何将每个过程链接到特定库中的特定对象文件。在下图中,PassA引用LLVMPasses.a中的PassA.o,而自定义过程则引用另一个库MyPasses.a中的MyPass.o对象文件。

img

代码生成器也像优化器一样,利用了这种模块化设计,将代码生成分解为若干个独立的过程,包括指令选择、寄存器分配、调度、代码布局优化和汇编代码生成。

在上述的每个阶段中,几乎每个目标都有一些共通之处,例如为虚拟寄存器分配可用的物理寄存器的算法,尽管不同目标的寄存器集合各不相同。因此,编译器的编写者可以修改上述的每个过程,并创建定制的针对特定目标的过程。使用 tablegen 工具和针对特定架构的表描述 .td 文件,可以帮助实现这一点。我们将在本书后面讨论这是如何实现的。

由此产生的另一个能力是,能够轻松地将一个错误定位到优化器中的特定过程。一个名为 Bugpoint 的工具利用了这一能力,可以自动缩减测试用例,并定位出导致错误的过程。

了解LLVM IR


LLVM的中间表示IR)是LLVM项目的核心。通常,每个编译器都会生成一个中间表示,然后在其上运行大部分优化。对于面向多源语言和不同架构的编译器,在选择IR时的一个重要决策是,它既不应是非常高级的,即与源语言紧密相连,也不应是非常低级的,即接近于目标机器指令。LLVM IR旨在成为一种通用的IR,通过处于足够低的级别,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值