finish write llvm-naive-0
This commit is contained in:
parent
33bc6692eb
commit
f3c48a29de
|
@ -1,10 +1,12 @@
|
|||
---
|
||||
title: LLVM入门笔记
|
||||
date: 2024-08-25T17:19:45.6572088+08:00
|
||||
tags:
|
||||
- 编译原理
|
||||
- LLVM
|
||||
- 技术笔记
|
||||
- 编译原理
|
||||
- LLVM
|
||||
- 技术笔记
|
||||
---
|
||||
|
||||
为什么说LLVM是神?
|
||||
|
||||
<!--more-->
|
||||
|
@ -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<dyn Error>> {
|
||||
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)
|
||||
|
BIN
YaeBlog/source/posts/llvm-naive-0/image-20240825171858276.png
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/llvm-naive-0/image-20240825171858276.png
(Stored with Git LFS)
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user