Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

删除不合适的 gep 指令说明 #63

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/tutorials/07-ir-generation-1-llvm.md
Original file line number Diff line number Diff line change
Expand Up @@ -1211,17 +1211,19 @@ LVal → Ident {'[' Exp ']'}

现在来理解一下上面这一条指令。第一个 `<ty>` 表示的是第一个索引所指向的类型,有时也是**返回值的类型**。第二个 `<ty>` 表示的是后面的指针基地址 `<ptrval>` 的类型, `<ty> <index>` 表示的是一组索引的类型和值,在本实验中索引的类型为 `i32`。索引指向的基本类型确定的是增加索引值时指针的偏移量。

说完理论,不如结合一个实例来讲解。考虑数组 `a[5]`,需要获取 `a[3]` 的地址,有如下写法
说完理论,不如结合一个实例来讲解。考虑数组 `a[5]`,需要获取 `a[3]` 的地址,有如下两种写法

```llvm
; 方法一
%1 = getelementptr [5 x i32], [5 x i32]* @a, i32 0, i32 3

; 方法二
%2 = getelementptr [5 x i32], [5 x i32]* @a, i32 0
%3 = getelementptr i32, i32* %2, i32 3

%3 = getelementptr i32, i32* @a, i32 3
```

当数组作为参数时,需要先将其转换为指针类型,即方法二中的第一条指令。在被调用的函数中,对于指针类型的参数,使用方法二中的第二条指令即可获取对应下标元素的地址。

### (2)数组定义与调用

这一章将主要讲述数组定义和调用,包括全局数组,局部数组的定义,以及函数中的数组调用。对于全局数组定义,与全局变量一样,同学们需要将所有量**全部计算到特定的值**。对于一个维度内全是 0 的地方,可以采用 `zeroinitializer` 来统一置 0。
Expand All @@ -1248,8 +1250,6 @@ char c[8] = "foobar";
@c = dso_local global [8 x i8] [i8 102, i8 111, i8 111, i8 98, i8 97, i8 114, i8 0, i8 0]
```

当然,`zeroinitializer` 不是必须的,同学们完全可以一个个 `i32 0` 写进去,但对于一些很阴间的样例点,不用 `zeroinitializer` 可能会导致 **TLE** ,例如全局数组 `int a[1000];` ,不使用该指令就需要输出 **1000 次 i32 0**,必然导致 TLE,所以还是推荐同学们使用 `zeroinitializer`。

对于局部数组,在定义的时候同样需要使用 `alloca` 指令,其存取指令同样采用 **load 和 store**,只是在此之前需要采用 `getelementptr` 获取数组内应位置的地址。

字符数组的字符串常量初始化,可以自行设计实现。LLVM IR 中,全局字符数组的字符串常量初始化可以直接通过字符串赋值,局部字符数组则也需要通过 `alloca` 指令分配内存空间,逐个元素初始化。不要忘记字符串常量末尾的结束符 '\00' 和填充符号 '\00'。
Expand Down