LLVM 架构设计与原理:为什么它能取代 GCC 成为新宠

LLVM 架构设计与原理:为什么它能取代 GCC 成为新宠

上一篇我们拆完了 GCC 的四阶段流程。这一篇换个角度:同样是编译器,LLVM 到底在设计上做了什么不同的事,让苹果愿意为它另起炉灶?

核心答案就一句话:把编译器拆成一堆可以独立复用的库,中间用一套统一的 IR 连起来。

文章目录

  • [LLVM 架构设计与原理:为什么它能取代 GCC 成为新宠](#LLVM 架构设计与原理:为什么它能取代 GCC 成为新宠)
    • [一、先看动机:GCC 的三个痛点](#一、先看动机:GCC 的三个痛点)
    • [二、LLVM 发展历程](#二、LLVM 发展历程)
      • [2.1 名字的由来(以及为什么现在不再是缩写)](#2.1 名字的由来(以及为什么现在不再是缩写))
      • [2.2 Clang 的诞生](#2.2 Clang 的诞生)
      • [2.3 生态地位](#2.3 生态地位)
    • [三、LLVM 的架构特点](#三、LLVM 的架构特点)
      • [3.1 一句话概括](#3.1 一句话概括)
      • [3.2 组件独立性:前后端终于可以各干各的](#3.2 组件独立性:前后端终于可以各干各的)
      • [3.3 IR:LLVM 的"通用货币"](#3.3 IR:LLVM 的"通用货币")
      • [3.4 IR 的三种表达形式](#3.4 IR 的三种表达形式)
      • [3.5 LLVM IR 的三个优点](#3.5 LLVM IR 的三个优点)
    • [四、LLVM 整体架构:前端 / 优化器 / 后端](#四、LLVM 整体架构:前端 / 优化器 / 后端)
      • [4.1 三段式全景](#4.1 三段式全景)
      • [4.2 Clang 前端的三步](#4.2 Clang 前端的三步)
      • [4.3 优化器:一堆 Pass 排队干活](#4.3 优化器:一堆 Pass 排队干活)
      • [4.4 后端:五步落地到机器码](#4.4 后端:五步落地到机器码)
    • [五、和 GCC 的关键差异](#五、和 GCC 的关键差异)
    • [六、Clang + LLVM 实战](#六、Clang + LLVM 实战)
      • [6.1 第一步:预处理](#6.1 第一步:预处理)
      • [6.2 第二步:生成 LLVM IR](#6.2 第二步:生成 LLVM IR)
      • [6.3 第三步:用 llc 编译成目标汇编](#6.3 第三步:用 llc 编译成目标汇编)
      • [6.4 第四步:汇编 + 链接成可执行文件](#6.4 第四步:汇编 + 链接成可执行文件)
      • [6.5 第五步:看穿整个编译过程](#6.5 第五步:看穿整个编译过程)
    • [七、LLVM 工具链速查](#七、LLVM 工具链速查)
    • 八、小结
    • 参考资料

一、先看动机:GCC 的三个痛点

LLVM 不是凭空出现的,它是被 GCC 的问题"逼"出来的。回顾上一篇总结的 GCC 缺点:

GCC 的痛点 具体表现 导致的后果
代码耦合度高 前端、优化器、后端代码交织在一起 想单独拿优化器出来用?做不到
难以作为 API 集成 设计上没考虑被别的工具调用 IDE 想接入语义分析,只能硬啃
代码量庞大 约 1500 万行 新开发者上手极难

对苹果来说,这些痛点尤其致命:

  1. 苹果在 Objective-C 上投入很大,但 GCC 社区对此不买账,双方分歧越来越大
  2. 苹果只能基于 GCC 拉出自己的分支独立维护,结果版本长期落后于官方 GCC
  3. 苹果想要更好的 IDE 集成,但 GCC 的模块化程度根本做不到

大白话 :GCC 像一台"一体化洗衣机"------洗、漂、脱全在一个铁壳子里,好用但拆不开。苹果想要的是"积木式"的东西:洗涤模块、烘干模块都能单独拿出来,还能接到自己家的柜子上。

于是苹果找到了编译器领域的专家 克里斯·拉特纳(Chris Lattner),LLVM 由此走上历史舞台。


二、LLVM 发展历程

#mermaid-svg-mkuwNn8ctxcSqd3f{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mkuwNn8ctxcSqd3f .error-icon{fill:#552222;}#mermaid-svg-mkuwNn8ctxcSqd3f .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mkuwNn8ctxcSqd3f .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mkuwNn8ctxcSqd3f .marker.cross{stroke:#333333;}#mermaid-svg-mkuwNn8ctxcSqd3f svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mkuwNn8ctxcSqd3f p{margin:0;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge{stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .section--1 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section--1 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section--1 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section--1 text{fill:#ffffff;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth--1{stroke-width:17;}#mermaid-svg-mkuwNn8ctxcSqd3f .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:#ffffff;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-0 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-0 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-0 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-0 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-0{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-0{stroke-width:14;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-1 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-1 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-1 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-1 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-1{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-1{stroke-width:11;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-2 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-2 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-2 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-2 text{fill:#ffffff;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-2{stroke-width:8;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:#ffffff;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-3 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-3 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-3 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-3 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-3{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-3{stroke-width:5;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-4 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-4 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-4 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-4 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-4{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-4{stroke-width:2;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-5 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-5 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-5 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-5 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-5{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-5{stroke-width:-1;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-6 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-6 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-6 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-6 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-6{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-6{stroke-width:-4;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-7 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-7 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-7 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-7 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-7{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-7{stroke-width:-7;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-8 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-8 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-8 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-8 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-8{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-8{stroke-width:-10;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-9 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-9 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-9 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-9 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-9{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-9{stroke-width:-13;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-10 rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-10 path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-10 circle,#mermaid-svg-mkuwNn8ctxcSqd3f .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-10 text{fill:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .node-icon-10{font-size:40px;color:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .edge-depth-10{stroke-width:-16;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-mkuwNn8ctxcSqd3f .lineWrapper line{stroke:black;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled circle,#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:lightgray;}#mermaid-svg-mkuwNn8ctxcSqd3f .disabled text{fill:#efefef;}#mermaid-svg-mkuwNn8ctxcSqd3f .section-root rect,#mermaid-svg-mkuwNn8ctxcSqd3f .section-root path,#mermaid-svg-mkuwNn8ctxcSqd3f .section-root circle{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-mkuwNn8ctxcSqd3f .section-root text{fill:#ffffff;}#mermaid-svg-mkuwNn8ctxcSqd3f .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-mkuwNn8ctxcSqd3f .edge{fill:none;}#mermaid-svg-mkuwNn8ctxcSqd3f .eventWrapper{filter:brightness(120%);}#mermaid-svg-mkuwNn8ctxcSqd3f :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 2000 UIUC 起步 Vikram Adve 与 Chris Lattner 开始研究 目标是为静态/动态语言创建动态编译技术 2003 正式开源 以 BSD 许可证发布 2005 苹果雇佣 Lattner 团队 用于 macOS / iOS 开发工具 2012 获 ACM 软件系统奖 表彰 Adve、Lattner、Evan Cheng 的贡献 2019 迁移到 GitHub 自 2019-10 起代码托管正式迁移 9.0.0 起 改用 Apache 2.0 带 LLVM 额外条款 LLVM 关键节点

2.1 名字的由来(以及为什么现在不再是缩写)

LLVM 最初是 Low Level Virtual Machine (低级虚拟机)的首字母缩写。但随着项目扩张,这个名字越来越容易误导人------因为它早就不只是一个虚拟机了。

于是开发者干脆放弃缩写的含义 ,把 LLVM 当成一个品牌名,用来指代整个项目下的所有子项目:

  • LLVM IR(中间表示)
  • Clang(C/C++/Obj-C 前端)
  • LLDB(调试器)
  • libc++(C++ 标准库)
  • 以及各种编译工具与底层工具技术

小白速查 :所以今天说"LLVM"时,不是在说"一台虚拟机",而是在说"一整套编译器基础设施"。这点很容易被名字带偏。

2.2 Clang 的诞生

LLVM 项目催生了很多语言的编译器,最出名的就是 Clang------支持 C、Objective-C、C++,由苹果大力支持。

Clang 的目标很明确:取代 GCC 在系统里的 C / Objective-C 编译器。它的优势在于:

  • 更容易集成到现代 IDE(因为它是库化的)
  • 对多线程支持更好
  • 从 Clang 3.8 起开始支持 OpenMP

与此同时,GCC 在 Objective-C 上的发展基本停滞,苹果把相关支持转到了自己的维护分支。

2.3 生态地位

2021 年 JetBrains 开发者调查:

编译器 使用率
GCC 78%
Clang 43%

值得注意的是:两者不是互斥选择,很多项目会同时用两套编译器做交叉验证(编译期告警、生成代码质量对比)。


三、LLVM 的架构特点

3.1 一句话概括

组件独立 + 库化设计 + 统一 IR。

这三件事互为一体:因为有了统一的 IR,前后端才能解耦;因为解耦了,各个组件才能被做成独立的库。
#mermaid-svg-rSt7CEdrDdTrHbE2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rSt7CEdrDdTrHbE2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rSt7CEdrDdTrHbE2 .error-icon{fill:#552222;}#mermaid-svg-rSt7CEdrDdTrHbE2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rSt7CEdrDdTrHbE2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rSt7CEdrDdTrHbE2 .marker.cross{stroke:#333333;}#mermaid-svg-rSt7CEdrDdTrHbE2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rSt7CEdrDdTrHbE2 p{margin:0;}#mermaid-svg-rSt7CEdrDdTrHbE2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rSt7CEdrDdTrHbE2 .cluster-label text{fill:#333;}#mermaid-svg-rSt7CEdrDdTrHbE2 .cluster-label span{color:#333;}#mermaid-svg-rSt7CEdrDdTrHbE2 .cluster-label span p{background-color:transparent;}#mermaid-svg-rSt7CEdrDdTrHbE2 .label text,#mermaid-svg-rSt7CEdrDdTrHbE2 span{fill:#333;color:#333;}#mermaid-svg-rSt7CEdrDdTrHbE2 .node rect,#mermaid-svg-rSt7CEdrDdTrHbE2 .node circle,#mermaid-svg-rSt7CEdrDdTrHbE2 .node ellipse,#mermaid-svg-rSt7CEdrDdTrHbE2 .node polygon,#mermaid-svg-rSt7CEdrDdTrHbE2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rSt7CEdrDdTrHbE2 .rough-node .label text,#mermaid-svg-rSt7CEdrDdTrHbE2 .node .label text,#mermaid-svg-rSt7CEdrDdTrHbE2 .image-shape .label,#mermaid-svg-rSt7CEdrDdTrHbE2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-rSt7CEdrDdTrHbE2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rSt7CEdrDdTrHbE2 .rough-node .label,#mermaid-svg-rSt7CEdrDdTrHbE2 .node .label,#mermaid-svg-rSt7CEdrDdTrHbE2 .image-shape .label,#mermaid-svg-rSt7CEdrDdTrHbE2 .icon-shape .label{text-align:center;}#mermaid-svg-rSt7CEdrDdTrHbE2 .node.clickable{cursor:pointer;}#mermaid-svg-rSt7CEdrDdTrHbE2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rSt7CEdrDdTrHbE2 .arrowheadPath{fill:#333333;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rSt7CEdrDdTrHbE2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rSt7CEdrDdTrHbE2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rSt7CEdrDdTrHbE2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rSt7CEdrDdTrHbE2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rSt7CEdrDdTrHbE2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rSt7CEdrDdTrHbE2 .cluster text{fill:#333;}#mermaid-svg-rSt7CEdrDdTrHbE2 .cluster span{color:#333;}#mermaid-svg-rSt7CEdrDdTrHbE2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rSt7CEdrDdTrHbE2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rSt7CEdrDdTrHbE2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-rSt7CEdrDdTrHbE2 .icon-shape,#mermaid-svg-rSt7CEdrDdTrHbE2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rSt7CEdrDdTrHbE2 .icon-shape p,#mermaid-svg-rSt7CEdrDdTrHbE2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rSt7CEdrDdTrHbE2 .icon-shape .label rect,#mermaid-svg-rSt7CEdrDdTrHbE2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rSt7CEdrDdTrHbE2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rSt7CEdrDdTrHbE2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rSt7CEdrDdTrHbE2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 后端 + 优化(可复用)
统一中间表示
前端(可替换)
Clang

C/C++/Obj-C
Flang

Fortran
Rustc

Rust
Swift
LLVM IR

强类型 · RISC 风格 · 目标无关
优化器

一系列 Pass
x86 后端
ARM 后端
RISC-V 后端
AMDGPU / NVPTX 后端

3.2 组件独立性:前后端终于可以各干各的

这是 LLVM 最核心的设计收益:

角色 只需要做什么 不需要做什么
前端工程师 把新语言翻译成 LLVM IR 完全不用碰优化器和后端
后端工程师 把 IR 对接目标硬件的寄存器、指令调度 完全不用管前端是 C 还是 Rust

大白话 :这就是"插座标准"的威力。只要大家都用同一种插头(IR),电器(前端)和电网(后端)就能自由组合------新语言想接入,做前端就行;新 CPU 想支持,做后端就行。

这直接解释了为什么 LLVM 能快速支持一堆新语言(Rust、Swift、Julia 等)和一堆新硬件(各种 GPU、AI 加速器)------大家都只需要做自己那一半。

3.3 IR:LLVM 的"通用货币"

LLVM IR 是一种类似汇编的底层语言,但有几个关键特征:

特征 含义
强类型 每个值都有明确类型(i32、ptr、float...),不像传统汇编那样"裸地址"
RISC 风格 精简指令集,指令少而规整,便于分析和变换
目标无关 抽象掉具体硬件的寄存器、调用约定等细节
显式控制流 用 br、ret、call 等指令显式表达,没有隐式跳转

举个具体例子:在 IR 里,函数调用惯例被抽象成 call 和 ret 指令,参数是明确写出来的 ,而不是像汇编那样依赖 ABI 约定(哪个参数放 rdi、返回值放 rax)。

一段 hello.c 对应的 IR(.ll,节选):

llvm 复制代码
@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1
; ↑ 字符串常量:13 字节的 i8 数组,"hello world\n\0"
;   private = 仅本模块可见;constant = 只读

declare i32 @printf(ptr, ...)
; ↑ 声明外部函数 printf:返回 i32,第一个参数是指针(格式串),后面是可变参数
;   注意这里没有"参数放哪个寄存器"------那是后端该操心的事

define i32 @main() {
; ↑ 定义 main:返回 i32
  %1 = call i32 (ptr, ...) @printf(ptr @.str)
  ; ↑ 调用 printf,传字符串常量地址;返回值存到 %1
  ret i32 0
  ; ↑ 返回 0
}

对比一下 :GCC 的 .s 里你会看到 movq %rsp, %rbp、leaq L_.str(%rip), %rdi 这种绑定 x86-64 ABI 的东西;而 LLVM IR 里只有 call @printf------寄存器分配和 ABI 落地都交给后端。这就是"目标无关"的含义。

3.4 IR 的三种表达形式

LLVM 提供了三种形态的 IR,各有用途:

形式 后缀 特点 典型用途
人类可读的文本 .ll 汇编风格文本,能直接看懂 调试、教学、写测试
内存中的 C++ 对象 --- 通过 C++ API 操作 写 Pass、做静态分析、构建工具
序列化 bitcode .bc 紧凑二进制,可跨版本读取 分发、LTO、离线优化

#mermaid-svg-9SiD6hrHgisvWqDq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9SiD6hrHgisvWqDq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9SiD6hrHgisvWqDq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9SiD6hrHgisvWqDq .error-icon{fill:#552222;}#mermaid-svg-9SiD6hrHgisvWqDq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9SiD6hrHgisvWqDq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9SiD6hrHgisvWqDq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9SiD6hrHgisvWqDq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9SiD6hrHgisvWqDq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9SiD6hrHgisvWqDq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9SiD6hrHgisvWqDq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9SiD6hrHgisvWqDq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9SiD6hrHgisvWqDq .marker.cross{stroke:#333333;}#mermaid-svg-9SiD6hrHgisvWqDq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9SiD6hrHgisvWqDq p{margin:0;}#mermaid-svg-9SiD6hrHgisvWqDq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9SiD6hrHgisvWqDq .cluster-label text{fill:#333;}#mermaid-svg-9SiD6hrHgisvWqDq .cluster-label span{color:#333;}#mermaid-svg-9SiD6hrHgisvWqDq .cluster-label span p{background-color:transparent;}#mermaid-svg-9SiD6hrHgisvWqDq .label text,#mermaid-svg-9SiD6hrHgisvWqDq span{fill:#333;color:#333;}#mermaid-svg-9SiD6hrHgisvWqDq .node rect,#mermaid-svg-9SiD6hrHgisvWqDq .node circle,#mermaid-svg-9SiD6hrHgisvWqDq .node ellipse,#mermaid-svg-9SiD6hrHgisvWqDq .node polygon,#mermaid-svg-9SiD6hrHgisvWqDq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9SiD6hrHgisvWqDq .rough-node .label text,#mermaid-svg-9SiD6hrHgisvWqDq .node .label text,#mermaid-svg-9SiD6hrHgisvWqDq .image-shape .label,#mermaid-svg-9SiD6hrHgisvWqDq .icon-shape .label{text-anchor:middle;}#mermaid-svg-9SiD6hrHgisvWqDq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9SiD6hrHgisvWqDq .rough-node .label,#mermaid-svg-9SiD6hrHgisvWqDq .node .label,#mermaid-svg-9SiD6hrHgisvWqDq .image-shape .label,#mermaid-svg-9SiD6hrHgisvWqDq .icon-shape .label{text-align:center;}#mermaid-svg-9SiD6hrHgisvWqDq .node.clickable{cursor:pointer;}#mermaid-svg-9SiD6hrHgisvWqDq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9SiD6hrHgisvWqDq .arrowheadPath{fill:#333333;}#mermaid-svg-9SiD6hrHgisvWqDq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9SiD6hrHgisvWqDq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9SiD6hrHgisvWqDq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9SiD6hrHgisvWqDq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9SiD6hrHgisvWqDq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9SiD6hrHgisvWqDq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9SiD6hrHgisvWqDq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9SiD6hrHgisvWqDq .cluster text{fill:#333;}#mermaid-svg-9SiD6hrHgisvWqDq .cluster span{color:#333;}#mermaid-svg-9SiD6hrHgisvWqDq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-9SiD6hrHgisvWqDq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9SiD6hrHgisvWqDq rect.text{fill:none;stroke-width:0;}#mermaid-svg-9SiD6hrHgisvWqDq .icon-shape,#mermaid-svg-9SiD6hrHgisvWqDq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9SiD6hrHgisvWqDq .icon-shape p,#mermaid-svg-9SiD6hrHgisvWqDq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9SiD6hrHgisvWqDq .icon-shape .label rect,#mermaid-svg-9SiD6hrHgisvWqDq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9SiD6hrHgisvWqDq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9SiD6hrHgisvWqDq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9SiD6hrHgisvWqDq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} llvm-as / llvm-dis
解析 / 序列化
C 源码
.ll

文本 IR
.bc

bitcode
内存中 IR

(C++ 对象)
llc
目标汇编 .s

三者可以互相转换:

bash 复制代码
llvm-as hello.ll -o hello.bc      # 文本 IR → bitcode
llvm-dis hello.bc -o hello.ll     # bitcode → 文本 IR
llvm-as hello.ll | llvm-dis       # 管道也行

3.5 LLVM IR 的三个优点

优点 说明
更独立 IR 被设计为可在编译器之外复用,所以静态分析器、插桩工具、优化工具都能直接接进来
更正式 有明确定义和规范化的 C++ API,处理、转换、分析都方便
更接近硬件 类似 RISC-V 的模拟指令集 + 强类型系统,既是"通用表示",又足够底层,便于做硬件级分析

为什么"更接近硬件"很重要? 因为如果 IR 太高层(比如直接是 AST),很多底层优化就做不了;如果太底层(比如直接是机器码),又没法跨平台。LLVM IR 卡在中间这个甜点区------既能表达机器级语义,又保持目标无关。


四、LLVM 整体架构:前端 / 优化器 / 后端

4.1 三段式全景

LLVM 是模块化、可重用的编译器和工具链技术库 。对用户来说,通常直接用的是 clang 命令,优化器和后端是透明的。
#mermaid-svg-QgsxwpUV3gyMmbNW{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QgsxwpUV3gyMmbNW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QgsxwpUV3gyMmbNW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QgsxwpUV3gyMmbNW .error-icon{fill:#552222;}#mermaid-svg-QgsxwpUV3gyMmbNW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QgsxwpUV3gyMmbNW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QgsxwpUV3gyMmbNW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QgsxwpUV3gyMmbNW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QgsxwpUV3gyMmbNW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QgsxwpUV3gyMmbNW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QgsxwpUV3gyMmbNW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QgsxwpUV3gyMmbNW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QgsxwpUV3gyMmbNW .marker.cross{stroke:#333333;}#mermaid-svg-QgsxwpUV3gyMmbNW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QgsxwpUV3gyMmbNW p{margin:0;}#mermaid-svg-QgsxwpUV3gyMmbNW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QgsxwpUV3gyMmbNW .cluster-label text{fill:#333;}#mermaid-svg-QgsxwpUV3gyMmbNW .cluster-label span{color:#333;}#mermaid-svg-QgsxwpUV3gyMmbNW .cluster-label span p{background-color:transparent;}#mermaid-svg-QgsxwpUV3gyMmbNW .label text,#mermaid-svg-QgsxwpUV3gyMmbNW span{fill:#333;color:#333;}#mermaid-svg-QgsxwpUV3gyMmbNW .node rect,#mermaid-svg-QgsxwpUV3gyMmbNW .node circle,#mermaid-svg-QgsxwpUV3gyMmbNW .node ellipse,#mermaid-svg-QgsxwpUV3gyMmbNW .node polygon,#mermaid-svg-QgsxwpUV3gyMmbNW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QgsxwpUV3gyMmbNW .rough-node .label text,#mermaid-svg-QgsxwpUV3gyMmbNW .node .label text,#mermaid-svg-QgsxwpUV3gyMmbNW .image-shape .label,#mermaid-svg-QgsxwpUV3gyMmbNW .icon-shape .label{text-anchor:middle;}#mermaid-svg-QgsxwpUV3gyMmbNW .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QgsxwpUV3gyMmbNW .rough-node .label,#mermaid-svg-QgsxwpUV3gyMmbNW .node .label,#mermaid-svg-QgsxwpUV3gyMmbNW .image-shape .label,#mermaid-svg-QgsxwpUV3gyMmbNW .icon-shape .label{text-align:center;}#mermaid-svg-QgsxwpUV3gyMmbNW .node.clickable{cursor:pointer;}#mermaid-svg-QgsxwpUV3gyMmbNW .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QgsxwpUV3gyMmbNW .arrowheadPath{fill:#333333;}#mermaid-svg-QgsxwpUV3gyMmbNW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QgsxwpUV3gyMmbNW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QgsxwpUV3gyMmbNW .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QgsxwpUV3gyMmbNW .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QgsxwpUV3gyMmbNW .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QgsxwpUV3gyMmbNW .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QgsxwpUV3gyMmbNW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QgsxwpUV3gyMmbNW .cluster text{fill:#333;}#mermaid-svg-QgsxwpUV3gyMmbNW .cluster span{color:#333;}#mermaid-svg-QgsxwpUV3gyMmbNW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QgsxwpUV3gyMmbNW .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QgsxwpUV3gyMmbNW rect.text{fill:none;stroke-width:0;}#mermaid-svg-QgsxwpUV3gyMmbNW .icon-shape,#mermaid-svg-QgsxwpUV3gyMmbNW .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QgsxwpUV3gyMmbNW .icon-shape p,#mermaid-svg-QgsxwpUV3gyMmbNW .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QgsxwpUV3gyMmbNW .icon-shape .label rect,#mermaid-svg-QgsxwpUV3gyMmbNW .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QgsxwpUV3gyMmbNW .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QgsxwpUV3gyMmbNW .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QgsxwpUV3gyMmbNW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ① 词法分析
② 语法分析
③ 语义分析 + IR 生成
Pass: 常量折叠 / 循环优化 / 死代码消除 ...
④ 指令选择
⑤ 寄存器分配
⑥ 指令调度 / 代码布局
C / C++ / Obj-C 源码
Clang 前端
Tokens
AST
LLVM IR
优化器(Optimizer)
优化后的 IR
后端(Back-End)
目标指令
已分配寄存器
机器码
目标平台可执行文件

层 职责
前端 Front-End 高级语言 → IR。Clang 负责 C/C++/Obj-C
优化器 Optimizer 对 IR 做各种变换,提升执行效率(目标无关)
后端 Back-End 优化后的 IR → 目标平台机器码(目标相关)

关键点 :优化发生在 IR 层 ,这就意味着同一套优化对所有语言、所有目标平台都生效。GCC 历史上前端和后端耦合较紧,优化常常和具体前端/目标绑在一起------这就是架构差异带来的实际收益。

4.2 Clang 前端的三步

步骤 英文 做什么
① 词法分析 Lexical Analysis 源码 → Token 流 (int、main、(......)
② 语法分析 Syntax Analysis Token 流 → 抽象语法树 AST
③ 语义分析 Semantic Analysis 检查类型/作用域是否合法,并生成 IR

小白速查 :AST 是"语法结构树",比如 a + b 会被表示成一个 BinaryOperator(+) 节点,左右子树是 a 和 b。语义分析才真正关心"a 和 b 类型能不能相加"。

4.3 优化器:一堆 Pass 排队干活

Pass 是 LLVM 优化的基本单位------每个 Pass 只做一件特定的事,然后按流水线顺序依次作用于 IR。

典型 Pass 做什么
常量折叠(Constant Folding) 编译期就能算的表达式直接算掉,如 2 * 3 → 6
循环优化 循环展开、循环交换等,提升循环效率
死代码消除(DCE) 删掉永远不会被执行或被使用的代码

大白话 :Pass 就像流水线上的工位------一号工位专管拧螺丝(常量折叠),二号工位专管抛光(循环优化),三号工位专管质检剔除(DCE)。每个工位只管一件事,互不干扰,组合起来就很灵活。

这也是为什么 LLVM 的优化器能被单独抽出来当库用 ------比如你在自己的工具里调 opt 工具或 PassBuilder 的 C++ API,就能跑同样的优化。

4.4 后端:五步落地到机器码

步骤 做什么
指令选择(Instruction Selection) IR 指令 → 目标架构指令(比如 call → callq)
寄存器分配(Register Allocation) 给虚拟寄存器分配真实物理寄存器;不够就溢出到栈
指令调度(Instruction Scheduling) 调整指令顺序,填满流水线、隐藏延迟
代码布局(Code Layout) 调整代码块排列,优化分支预测与 I-Cache 命中
代码生成(Code Generation) 输出目标平台汇编 + 最终机器码

注意 :这五步全部是目标相关的 。x86 有 16 个通用寄存器,RISC-V 有 32 个,GPU 又是另一套体系------所以每个目标都需要一个自己的后端(X86、AArch64、AMDGPU......)。


五、和 GCC 的关键差异

#mermaid-svg-6KgmVTsvfK99ZnIB{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6KgmVTsvfK99ZnIB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6KgmVTsvfK99ZnIB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6KgmVTsvfK99ZnIB .error-icon{fill:#552222;}#mermaid-svg-6KgmVTsvfK99ZnIB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6KgmVTsvfK99ZnIB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6KgmVTsvfK99ZnIB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6KgmVTsvfK99ZnIB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6KgmVTsvfK99ZnIB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6KgmVTsvfK99ZnIB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6KgmVTsvfK99ZnIB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6KgmVTsvfK99ZnIB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6KgmVTsvfK99ZnIB .marker.cross{stroke:#333333;}#mermaid-svg-6KgmVTsvfK99ZnIB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6KgmVTsvfK99ZnIB p{margin:0;}#mermaid-svg-6KgmVTsvfK99ZnIB .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-6KgmVTsvfK99ZnIB .cluster-label text{fill:#333;}#mermaid-svg-6KgmVTsvfK99ZnIB .cluster-label span{color:#333;}#mermaid-svg-6KgmVTsvfK99ZnIB .cluster-label span p{background-color:transparent;}#mermaid-svg-6KgmVTsvfK99ZnIB .label text,#mermaid-svg-6KgmVTsvfK99ZnIB span{fill:#333;color:#333;}#mermaid-svg-6KgmVTsvfK99ZnIB .node rect,#mermaid-svg-6KgmVTsvfK99ZnIB .node circle,#mermaid-svg-6KgmVTsvfK99ZnIB .node ellipse,#mermaid-svg-6KgmVTsvfK99ZnIB .node polygon,#mermaid-svg-6KgmVTsvfK99ZnIB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6KgmVTsvfK99ZnIB .rough-node .label text,#mermaid-svg-6KgmVTsvfK99ZnIB .node .label text,#mermaid-svg-6KgmVTsvfK99ZnIB .image-shape .label,#mermaid-svg-6KgmVTsvfK99ZnIB .icon-shape .label{text-anchor:middle;}#mermaid-svg-6KgmVTsvfK99ZnIB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6KgmVTsvfK99ZnIB .rough-node .label,#mermaid-svg-6KgmVTsvfK99ZnIB .node .label,#mermaid-svg-6KgmVTsvfK99ZnIB .image-shape .label,#mermaid-svg-6KgmVTsvfK99ZnIB .icon-shape .label{text-align:center;}#mermaid-svg-6KgmVTsvfK99ZnIB .node.clickable{cursor:pointer;}#mermaid-svg-6KgmVTsvfK99ZnIB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6KgmVTsvfK99ZnIB .arrowheadPath{fill:#333333;}#mermaid-svg-6KgmVTsvfK99ZnIB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6KgmVTsvfK99ZnIB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6KgmVTsvfK99ZnIB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6KgmVTsvfK99ZnIB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6KgmVTsvfK99ZnIB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6KgmVTsvfK99ZnIB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6KgmVTsvfK99ZnIB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6KgmVTsvfK99ZnIB .cluster text{fill:#333;}#mermaid-svg-6KgmVTsvfK99ZnIB .cluster span{color:#333;}#mermaid-svg-6KgmVTsvfK99ZnIB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6KgmVTsvfK99ZnIB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6KgmVTsvfK99ZnIB rect.text{fill:none;stroke-width:0;}#mermaid-svg-6KgmVTsvfK99ZnIB .icon-shape,#mermaid-svg-6KgmVTsvfK99ZnIB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6KgmVTsvfK99ZnIB .icon-shape p,#mermaid-svg-6KgmVTsvfK99ZnIB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6KgmVTsvfK99ZnIB .icon-shape .label rect,#mermaid-svg-6KgmVTsvfK99ZnIB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6KgmVTsvfK99ZnIB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6KgmVTsvfK99ZnIB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6KgmVTsvfK99ZnIB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} LLVM:库化 + 统一 IR
Clang
LLVM IR
Rust / Swift / Flang
优化器 Pass 流水线

(独立库 opt)
X86 后端
AArch64 后端
AMDGPU 后端
GCC:紧耦合
C 前端
GENERIC / GIMPLE
C++ 前端
优化 + 后端

(与前端共享大量内部结构)
x86
ARM

维度 GCC LLVM
架构耦合 高,前后端共享内部结构 低,靠 IR 解耦
能否当库嵌入 困难 天然支持(组件即库)
新增语言 需深入 GCC 内部 只需写前端生成 IR
新增后端 需适配 GCC 内部接口 只需实现 Target 后端
优化位置 与前端/后端交织 统一在 IR 层
IR 可读性 内部格式,外部难用 .ll 文本 + 稳定 C++ API
许可证 GPL(传染性强) 早期 BSD,9.0 起 Apache 2.0 + LLVM 例外

性能对比的诚实说法 :原文提到 2011 年测试 LLVM 运行时平均比 GCC 低约 10%,2013 年测试则显示两者已接近。十几年过去,这个数字早已不能直接引用------现代版本上两者互有胜负,具体取决于代码特征和优化选项。真要比较,应该拿你自己项目的 benchmark 实测。


六、Clang + LLVM 实战

还是用那段 hello.c,这次走 Clang 路线,看看每一步产物。

6.1 第一步:预处理

bash 复制代码
clang -E hello.c -o hello.i

原文有一处小问题 :写的是 clang -E -c hello.c -o hello.i。-E(只预处理)和 -c(只编译不链接)语义冲突,-c 在这里是多余的 ,建议只用 -E。

产物 hello.i 是展开后的纯 C 代码。

6.2 第二步:生成 LLVM IR

有两种写法:

bash 复制代码
# 写法 A:生成 bitcode(二进制)
clang -emit-llvm -c hello.i -o hello.bc

# 写法 B:生成可读的文本 IR
clang -emit-llvm -S hello.c -o hello.ll
命令 产物 说明
-emit-llvm -c .bc 紧凑二进制 bitcode
-emit-llvm -S .ll 人类可读的 IR 文本

小白速查 :-S 的意思是"停在汇编/IR 阶段,输出文本";不加 -S 时 LLVM 默认输出二进制。所以 -emit-llvm -S = 文本 IR,-emit-llvm -c = bitcode。

6.3 第三步:用 llc 编译成目标汇编

bash 复制代码
llc hello.ll -o hello.s
llc hello.bc -o hello2.s

因为 .ll 和 .bc 表达的是完全相同的代码逻辑 ,所以生成的 hello.s 和 hello2.s 内容一致。

llc 就是"LLVM Compiler"------它承接的是已优化/未优化的 IR,往下走指令选择、寄存器分配、代码生成。

6.4 第四步:汇编 + 链接成可执行文件

bash 复制代码
clang hello.s -o hello

Clang 会自动调用汇编器把 .s 变成 .o,再调用链接器生成可执行文件。

6.5 第五步:看穿整个编译过程

bash 复制代码
clang -ccc-print-phases hello.c

输出:

复制代码
                +- 0: input, "hello.c", c
            +- 1: preprocessor, {0}, cpp-output
        +- 2: compiler, {1}, ir
    +- 3: backend, {2}, assembler
  +- 4: assembler, {3}, object
  +- 5: linker, {4}, image
6: bind-arch, "x86_64", {5}, image

这张图的读法({n} 表示"输入来自第 n 步"):
#mermaid-svg-IUxJSqzmYYKUBy9A{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IUxJSqzmYYKUBy9A .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IUxJSqzmYYKUBy9A .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IUxJSqzmYYKUBy9A .error-icon{fill:#552222;}#mermaid-svg-IUxJSqzmYYKUBy9A .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IUxJSqzmYYKUBy9A .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IUxJSqzmYYKUBy9A .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IUxJSqzmYYKUBy9A .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IUxJSqzmYYKUBy9A .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IUxJSqzmYYKUBy9A .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IUxJSqzmYYKUBy9A .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IUxJSqzmYYKUBy9A .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IUxJSqzmYYKUBy9A .marker.cross{stroke:#333333;}#mermaid-svg-IUxJSqzmYYKUBy9A svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IUxJSqzmYYKUBy9A p{margin:0;}#mermaid-svg-IUxJSqzmYYKUBy9A .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-IUxJSqzmYYKUBy9A .cluster-label text{fill:#333;}#mermaid-svg-IUxJSqzmYYKUBy9A .cluster-label span{color:#333;}#mermaid-svg-IUxJSqzmYYKUBy9A .cluster-label span p{background-color:transparent;}#mermaid-svg-IUxJSqzmYYKUBy9A .label text,#mermaid-svg-IUxJSqzmYYKUBy9A span{fill:#333;color:#333;}#mermaid-svg-IUxJSqzmYYKUBy9A .node rect,#mermaid-svg-IUxJSqzmYYKUBy9A .node circle,#mermaid-svg-IUxJSqzmYYKUBy9A .node ellipse,#mermaid-svg-IUxJSqzmYYKUBy9A .node polygon,#mermaid-svg-IUxJSqzmYYKUBy9A .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IUxJSqzmYYKUBy9A .rough-node .label text,#mermaid-svg-IUxJSqzmYYKUBy9A .node .label text,#mermaid-svg-IUxJSqzmYYKUBy9A .image-shape .label,#mermaid-svg-IUxJSqzmYYKUBy9A .icon-shape .label{text-anchor:middle;}#mermaid-svg-IUxJSqzmYYKUBy9A .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-IUxJSqzmYYKUBy9A .rough-node .label,#mermaid-svg-IUxJSqzmYYKUBy9A .node .label,#mermaid-svg-IUxJSqzmYYKUBy9A .image-shape .label,#mermaid-svg-IUxJSqzmYYKUBy9A .icon-shape .label{text-align:center;}#mermaid-svg-IUxJSqzmYYKUBy9A .node.clickable{cursor:pointer;}#mermaid-svg-IUxJSqzmYYKUBy9A .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-IUxJSqzmYYKUBy9A .arrowheadPath{fill:#333333;}#mermaid-svg-IUxJSqzmYYKUBy9A .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IUxJSqzmYYKUBy9A .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IUxJSqzmYYKUBy9A .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IUxJSqzmYYKUBy9A .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-IUxJSqzmYYKUBy9A .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IUxJSqzmYYKUBy9A .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-IUxJSqzmYYKUBy9A .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IUxJSqzmYYKUBy9A .cluster text{fill:#333;}#mermaid-svg-IUxJSqzmYYKUBy9A .cluster span{color:#333;}#mermaid-svg-IUxJSqzmYYKUBy9A div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-IUxJSqzmYYKUBy9A .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-IUxJSqzmYYKUBy9A rect.text{fill:none;stroke-width:0;}#mermaid-svg-IUxJSqzmYYKUBy9A .icon-shape,#mermaid-svg-IUxJSqzmYYKUBy9A .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IUxJSqzmYYKUBy9A .icon-shape p,#mermaid-svg-IUxJSqzmYYKUBy9A .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-IUxJSqzmYYKUBy9A .icon-shape .label rect,#mermaid-svg-IUxJSqzmYYKUBy9A .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IUxJSqzmYYKUBy9A .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-IUxJSqzmYYKUBy9A .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-IUxJSqzmYYKUBy9A :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 0 输入

hello.c
1 预处理

cpp-output
2 编译

ir
3 后端

assember(汇编文本)
4 汇编器

object
5 链接器

image
6 绑定架构

x86_64 可执行文件

编号 阶段 说明
0 input 读入 hello.c
1 preprocessor 预处理(宏展开、头文件展开)
2 compiler 前端编译 → IR
3 backend 后端:IR → 汇编文本
4 assembler 汇编器:汇编 → 目标文件 .o
5 linker 链接:目标文件 + 库 → image
6 bind-arch 按 x86_64 架构产出最终可执行文件

原文这里有两处小误 :一是把第 3 步说成"后端优化"、第 4 步说成"产生汇编指令"------准确地说 3 是后端(IR→汇编文本),4 是汇编器(汇编→目标文件) ;二是原文把第 6 步写成 bind-arch,"x86_64",实际输出里 bind-arch 与 "x86_64" 之间没有引号内逗号。按上面表格理解即可。


七、LLVM 工具链速查

工具 作用 常用命令
clang C/C++/Obj-C 前端 + 驱动 clang -emit-llvm -S hello.c -o hello.ll
llc IR → 目标汇编 llc hello.ll -o hello.s
opt IR 优化(跑 Pass) opt -O2 hello.ll -S -o hello.opt.ll
llvm-as 文本 IR → bitcode llvm-as hello.ll -o hello.bc
llvm-dis bitcode → 文本 IR llvm-dis hello.bc -o hello.ll
llvm-mc 汇编器(MC 层) llvm-mc -show-encoding
lli 直接解释执行 IR lli hello.bc
llvm-objdump 反汇编目标文件 llvm-objdump -d hello.o
clang -ccc-print-phases 打印编译阶段图 见上一节

八、小结

# 结论
1 LLVM 诞生于 GCC 的高耦合、难集成、代码庞大三大痛点,由苹果推动、Lattner 主导
2 LLVM 不再是"低级虚拟机"的缩写,而是整个编译器基础设施的品牌名
3 核心设计三件套:组件独立 + 库化 + 统一 IR
4 IR 让前后端彻底解耦------新语言只需写前端,新硬件只需写后端
5 IR 有三种形态:.ll 文本 / .bc bitcode / C++ 对象,可互相转换
6 优化全部发生在 IR 层,因此一套优化能服务所有语言和所有目标
7 后端五步:指令选择 → 寄存器分配 → 指令调度 → 代码布局 → 代码生成
8 相比 GCC,LLVM 的可嵌入性是它最大的结构性优势

一句话记住 LLVM :它把"编译"从一台整机,变成了一箱标准件。


参考资料

相关推荐
外收内放1 小时前
FastAPI猜字谜实战(3):把每一局存成JSON
开发语言·python·学习·json·fastapi
tedcloud1231 小时前
Docker Compose 部署 Memos:从安装到备份恢复
linux·开发语言·jvm·后端·docker·容器·rust
镜子AI1 小时前
镜子AI案例工程复盘:用Python给GEO效果做抽样检测与置信区间估计
开发语言·人工智能·python
春涧草茶1 小时前
慢就是快15-1 多进程 多线程
开发语言·python
pan_junbiao1 小时前
Go语言中的空白标识符
开发语言·后端·golang
卡卡~~1 小时前
C++学习
开发语言·c++
qetfw2 小时前
Bash 基础:脚本执行、引号与命令替换验证
linux·开发语言·chrome·bash
杜 硕2 小时前
从零开始的C++生活——第四讲
开发语言·c++·生活
云和数据.ChenGuang2 小时前
Python 集合(set)常用函数详解与实战案例
开发语言·python·深度学习·langchain