Clang && LLVM

截止先阶段,还只能将网上现有的知识融汇起来,未能深入源码做细致分析。https://www.zhihu.com/search?type=content&q=LLVM%20pass

编译过程主要可以划分为前端与后端:

1. 前端把源代码翻译成中间表示(IR)

2. 后端对前端生成的IR做优化,并编译成目标平台的机器码。

经典编译器gcc的问题是提供从前端到后端的一条龙服务,大量代码强耦合,不会暴露中间接口来给用户操作它的IR。

LLVM核心设计了一个叫LLVM IR的中间表示,并以libray的方式提供一系列接口,提供诸如操作IR、生成目标平台代码等后端功能。

LLVM包含了多个部分,项目核心部分是"LLVM", 包含了全部的工具,库,需要的头文件。它会处理中间表示,并将其转为目标文件。工具包含汇编器,反汇编器,比特码分析器,比特码优化器,也包含了基本的回归测试。

Clang是一个基于LLVM的编译器驱动,它提供了把C/C++/Objective-C翻译成LLVM IR的前端,并使用LLVM的库实现了LLVM IR到目标平台的后端。为什么叫编译器驱动呢?因为在使用clang main.cpp -o main的时候,Clang帮你“驱动”了C语言预处理器、C语言前端、LLVM后端、链接器等等。其实GNU gcc也是编译器驱动。

 

Pass就是“遍历一遍IR,可以同时对它做一些操作”的意思。在实现上,LLVM的核心库中会给你一些Pass类去继承。你需要实现它的一些方法。最后使用LLVM的编译器会把它翻译得到的IR传入Pass里,给你遍历和修改。

LLVM Pass有什么用?

1、插桩。在Pass遍历LLVM IR的同时,往里面插入新的代码。

2、机器无关的代码优化。IR在被翻译成机器码之前,会做一些机器无关的优化。但不同的优化方法之间需要解耦。所以自然要各自遍历一遍IR,实现一个个LLVM Pass。

3、静态分析。像VSCode的C/C++插件会用LLVM Pass来分析代码,提示可能的错误(无用的变量、无法到达的代码等等)

LLVM提供的可执行工具:

1. llvm-as

2. llvm-dis

3. opt: 优化LLVM IR,输出新的LLVM IR。

4. llc: 把LLVM IR编译成汇编码。需要用as进一步得到机器码。

5. lli:解释执行LLVM IR。

LLVM IR:https://llvm.org/devmtg/2019-04/slides/Tutorial-Bridgers-LLVM_IR_tutorial.pdf

 

LLVM IR有三种表示:

1. .ll格式:人类可阅读文本。

2. .bc格式:适合机器存储的二级制文件。

3. 内存表示。

.c -> .ll: clang -emit-llvm -S a.c -o a.ll

.c -> .bc: clang -emit-llvm -c a.c -o a.bc

.ll -> .bc: llvm-as a.ll -o a.bc

.bc -> .ll: llvm-dis a.bc -o a.ll

.bc -> .s: llc a.bc -i a.s

 

如何写一个LLVM Pass?

官方教程:https://llvm.org/docs/WritingAnLLVMPass.html

你可能感兴趣的:(LLVM)