LLVM(Low Level Virtual Machine)介绍

因为用了一下numba库,效果很好,得知其底层是LLVM,便一起学习了以下,顺带做个分享~

LLVM(Low Level Virtual Machine)是一个开源的编译器基础设施项目,它提供了一套可重用的编译器工具链技术。以下是关于LLVM的详细介绍:

1. LLVM概述

基本概念

  • 名称来源:最初代表"Low Level Virtual Machine",但现在已不再强调这个全称
  • 核心思想:提供模块化、可重用的编译器和工具链组件
  • 创始:由Chris Lattner在伊利诺伊大学香槟分校发起,现在由LLVM基金会管理

主要特点

  • 模块化设计:各个组件可以独立使用
  • 中间表示(IR):统一的代码表示形式
  • 跨平台支持:支持多种CPU架构和操作系统
  • 开源社区:拥有活跃的开源社区贡献

2. LLVM架构组成

核心组件

复制代码
前端 → LLVM IR → 优化器 → 后端 → 目标代码
2.1 前端(Frontend)
  • 作用:将源代码转换为LLVM IR
  • 支持的语言
    • Clang (C/C++/Objective-C)
    • Swift
    • Rust
    • Kotlin
    • 以及其他语言的前端
2.2 LLVM IR(中间表示)
llvm 复制代码
; 示例LLVM IR代码
define i32 @add(i32 %a, i32 %b) {
entry:
  %result = add i32 %a, %b
  ret i32 %result
}

IR特点

  • 静态单赋值形式(SSA)
  • 强类型系统
  • 平台无关
  • 可读的文本格式和高效的二进制格式
2.3 优化器(Optimizer)
  • 作用:对IR进行各种优化
  • 优化级别:-O0到-O3,-Os(大小优化)
  • 优化技术
    • 死代码消除
    • 内联展开
    • 循环优化
    • 常量传播等
2.4 后端(Backend)
  • 作用:将优化后的IR转换为目标机器代码
  • 支持的目标架构
    • x86/x86-64
    • ARM
    • PowerPC
    • MIPS
    • RISC-V等

3. LLVM工具链

主要工具

bash 复制代码
# 编译器前端
clang -  C/C++/Objective-C编译器

# IR工具
llvm-as - 将LLVM IR文本汇编为二进制格式
llvm-dis - 将LLVM IR二进制反汇编为文本格式
opt - LLVM IR优化器

# 后端工具
llc - LLVM静态编译器
lli - LLVM IR解释器和JIT编译器

# 其他工具
llvm-link - LLVM IR链接器
llvm-ar - LLVM归档器
llvm-objdump - 目标文件反汇编器

4. 实际应用场景

4.1 编程语言开发

cpp 复制代码
// 使用LLVM API创建简单函数的示例
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"

using namespace llvm;

Module* createSampleModule() {
    auto module = new Module("test", getGlobalContext());
    
    // 创建函数类型: int add(int, int)
    FunctionType *funcType = FunctionType::get(
        Type::getInt32Ty(getGlobalContext()),
        {Type::getInt32Ty(getGlobalContext()), Type::getInt32Ty(getGlobalContext())},
        false
    );
    
    // 创建函数
    Function *func = Function::Create(
        funcType,
        Function::ExternalLinkage,
        "add",
        module
    );
    
    return module;
}

4.2 JIT编译

cpp 复制代码
// 简单的JIT编译示例
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JIT.h"

void simpleJITExample() {
    // 创建模块和函数
    Module* module = createSampleModule();
    
    // 创建JIT执行引擎
    ExecutionEngine* engine = EngineBuilder(module).create();
    
    // 获取函数指针并执行
    void* addFunc = engine->getPointerToFunction(module->getFunction("add"));
    // 调用编译后的函数...
}

5. LLVM生态系统

相关项目

  • Clang:C语言家族编译器
  • LLDB:调试器
  • libc++:C++标准库实现
  • OpenMP:并行编程支持
  • MLIR:多级中间表示(新兴项目)

工业应用

  • Apple:Xcode工具链的核心(取代GCC)
  • Google:Android NDK,TensorFlow
  • NVIDIA:CUDA编译器
  • Mozilla:Rust编译器后端
  • 很多其他公司:AMD, Intel, ARM等

6. LLVM的优势

技术优势

  1. 模块化设计

    cpp 复制代码
    // 可以单独使用各个组件
    Module* module = parseSourceCode(source);
    optimizeModule(module, OptimizationLevel::O2);
    TargetMachine* target = createTargetMachine();
    emitObjectCode(module, target);
  2. 统一的中间表示

    • 所有语言共享相同的优化器和后端
    • 新的语言只需要实现前端
  3. 优秀的诊断信息

    bash 复制代码
    # Clang提供清晰的错误信息
    $ clang -c test.c
    test.c:5:10: error: use of undeclared identifier 'undefined_var'
    return undefined_var;
           ^
  4. 快速编译

    • Clang通常比GCC编译更快
    • 内存占用更低

7. 学习资源

入门资料

  • 官方文档llvm.org/docs
  • 教程:LLVM Kaleidoscope教程
  • 书籍:《LLVM Cookbook》

开发环境设置

bash 复制代码
# 获取LLVM源码
git clone https://github.com/llvm/llvm-project.git

# 构建LLVM
cd llvm-project
mkdir build && cd build
cmake -DLLVM_ENABLE_PROJECTS="clang" ../llvm
make -j$(nproc)

8. 实际用例:创建简单编译器

cpp 复制代码
// 使用LLVM创建简单计算器编译器
class SimpleCalculatorCompiler {
    LLVMContext context;
    IRBuilder<> builder;
    std::unique_ptr<Module> module;
    
public:
    SimpleCalculatorCompiler() : builder(context) {
        module = std::make_unique<Module>("simple_calc", context);
    }
    
    Function* createAddFunction() {
        // 创建加法函数
        FunctionType* funcType = FunctionType::get(
            Type::getInt32Ty(context),
            {Type::getInt32Ty(context), Type::getInt32Ty(context)},
            false
        );
        
        Function* func = Function::Create(
            funcType,
            Function::ExternalLinkage,
            "add",
            module.get()
        );
        
        // 创建基本块和代码
        BasicBlock* entry = BasicBlock::Create(context, "entry", func);
        builder.SetInsertPoint(entry);
        
        // 获取参数
        Value* arg1 = &*func->arg_begin();
        Value* arg2 = &*(std::next(func->arg_begin()));
        
        // 创建加法指令
        Value* result = builder.CreateAdd(arg1, arg2, "addresult");
        builder.CreateRet(result);
        
        return func;
    }
};

总结

LLVM是现代编译器技术的基石,它的主要价值在于:

  1. 模块化:可以单独使用各个组件
  2. 可重用性:新的语言可以复用现有的优化器和后端
  3. 性能:产生高质量的机器代码
  4. 工具支持:提供完整的工具链生态系统

无论是开发新的编程语言,还是进行代码分析、优化,或是构建开发工具,LLVM都提供了强大的基础设施支持。

相关推荐
程序员敲代码吗17 分钟前
用Python生成艺术:分形与算法绘图
jvm·数据库·python
Yyyyy123jsjs20 分钟前
如何通过免费的外汇API轻松获取实时汇率数据
开发语言·python
喵手29 分钟前
Python爬虫实战:GovDataMiner —— 开放数据门户数据集元数据采集器(附 CSV 导出)!
爬虫·python·爬虫实战·python爬虫工程化实战·零基础python爬虫教学·open data·开放数据门户数据集列表
历程里程碑42 分钟前
滑动窗口---- 无重复字符的最长子串
java·数据结构·c++·python·算法·leetcode·django
人工智能AI技术1 小时前
【Agent从入门到实践】43 接口封装:将Agent封装为API服务,供其他系统调用
人工智能·python
Darkershadow2 小时前
蓝牙学习之Time Set
python·学习·蓝牙·ble·mesh
m0_736919103 小时前
超越Python:下一步该学什么编程语言?
jvm·数据库·python
学习中的DGR3 小时前
[极客大挑战 2019]Http 1 新手解题过程
网络·python·网络协议·安全·http
布茹 ei ai3 小时前
Python屏幕监视器 - 自动检测屏幕变化并点击
开发语言·python