diff --git a/YaeBlog/source/drafts/llvm-naive-0.md b/YaeBlog/source/posts/llvm-naive-0.md similarity index 81% rename from YaeBlog/source/drafts/llvm-naive-0.md rename to YaeBlog/source/posts/llvm-naive-0.md index bdacdc4..100a501 100644 --- a/YaeBlog/source/drafts/llvm-naive-0.md +++ b/YaeBlog/source/posts/llvm-naive-0.md @@ -1,10 +1,12 @@ --- title: LLVM入门笔记 +date: 2024-08-25T17:19:45.6572088+08:00 tags: - - 编译原理 - - LLVM - - 技术笔记 +- 编译原理 +- LLVM +- 技术笔记 --- + 为什么说LLVM是神? @@ -156,13 +158,13 @@ main: # @main LLVM中间语言是一个基于静态单赋值的,类型安全的低级别中间表示形式。中间语言一般情况下有三种表示形式:内存中的数据结构、便于JIT编译器解析执行的字节码形式和人类可读的文本形式。 -> **良好定义(Well formed)**的中间语言:中间语言可以是在语义上没有问题的,但是并不是良好定义的。例如: +> **良好定义(Well formed)** 的中间语言:中间语言可以是在语义上没有问题的,但是并不是良好定义的。例如: > > ``` > %x = add i32 1, %x > ``` > -> 这段IR在语法上没有任何问题,但是并不是静态单赋值形式的。 +> 这段IR在语法上没有任何问题,但是变量`%x`的定义并不在所有的使用之前。 > > LLVM提供了一个Pass在运行所有的优化之前验证输入的IR是否是良好定义的。 @@ -207,6 +209,14 @@ LLVM中的关键词同其他语言中的关键词也非常类似,例如对于 ### 高级别表示 +这里使用LLVM在Rust中的高级别封装[inkwell](https://github.com/TheDan64/inkwell)示范如何使用LLVM IR编写一个简单的程序。在这个程序中涉及到LLVM几个重要的基础概念。 + +- `context`,LLVM中的上下文。这个对象中保存了LLVM IR中的一些重要全局状态,借助这个变量我们可以方便的将LLVM并行运行起来。 +- `module`,LLVM的模块,一个编译的单元,可以包含各种函数和全局变量。 +- `type`,LLVM中对于数据类型的抽象,通过基础类型的各种组合可以构建出更复杂的类型,例如函数和结构体。 +- `function`:LLVM中的函数,函数需要通过函数类型和名称来定义,函数类型需要通过输入参数类型和返回类型来定义。函数中可以通过附加上基本块来定义函数的实现。 +- `basic_block`:LLVM中的基本块,组成控制流的基本单元,中间包含从上到下依次执行的一系列指令序列。 + ```rust fn main() -> Result<(), Box> { let context = Context::create(); @@ -235,3 +245,28 @@ LLVM中的关键词同其他语言中的关键词也非常类似,例如对于 } ``` +执行上面的Rust代码,可以得到一段生成的LLVM IR代码: + +```llvm +; ModuleID = 'main' +source_filename = "main" + +@str = private unnamed_addr constant [13 x i8] c"Hello, LLVM!\00", align 1 +@format = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +declare i32 @puts(ptr) + +declare i32 @printf(ptr, i32, ...) + +define i32 @main() { +entry: + %0 = call i32 @puts(ptr @str) + %1 = call i32 (ptr, i32, ...) @printf(ptr @format, i32 3) + ret i32 0 +} +``` + +使用`lli`解释器可以直接运行这段代码: + +![image-20240825171858276](./llvm-naive-0/image-20240825171858276.png) + diff --git a/YaeBlog/source/drafts/llvm-naive-0/image-20240819213039409.png b/YaeBlog/source/posts/llvm-naive-0/image-20240819213039409.png similarity index 100% rename from YaeBlog/source/drafts/llvm-naive-0/image-20240819213039409.png rename to YaeBlog/source/posts/llvm-naive-0/image-20240819213039409.png diff --git a/YaeBlog/source/drafts/llvm-naive-0/image-20240819213624927.png b/YaeBlog/source/posts/llvm-naive-0/image-20240819213624927.png similarity index 100% rename from YaeBlog/source/drafts/llvm-naive-0/image-20240819213624927.png rename to YaeBlog/source/posts/llvm-naive-0/image-20240819213624927.png diff --git a/YaeBlog/source/drafts/llvm-naive-0/image-20240820221413791.png b/YaeBlog/source/posts/llvm-naive-0/image-20240820221413791.png similarity index 100% rename from YaeBlog/source/drafts/llvm-naive-0/image-20240820221413791.png rename to YaeBlog/source/posts/llvm-naive-0/image-20240820221413791.png diff --git a/YaeBlog/source/posts/llvm-naive-0/image-20240825171858276.png b/YaeBlog/source/posts/llvm-naive-0/image-20240825171858276.png new file mode 100644 index 0000000..6f13bdf --- /dev/null +++ b/YaeBlog/source/posts/llvm-naive-0/image-20240825171858276.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f198e93178db7a98fd7e2c0ffb3fc387d5b8793b37bed1cd0068d9f177a49ba6 +size 13107