Skip to content

Commit 9e96aed

Browse files
authored
删除不合适的 gep 指令说明 (#63)
1 parent b5b777d commit 9e96aed

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

docs/tutorials/07-ir-generation-1-llvm.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -1211,17 +1211,19 @@ LVal → Ident {'[' Exp ']'}
12111211
12121212
现在来理解一下上面这一条指令。第一个 `<ty>` 表示的是第一个索引所指向的类型,有时也是**返回值的类型**。第二个 `<ty>` 表示的是后面的指针基地址 `<ptrval>` 的类型, `<ty> <index>` 表示的是一组索引的类型和值,在本实验中索引的类型为 `i32`。索引指向的基本类型确定的是增加索引值时指针的偏移量。
12131213
1214-
说完理论,不如结合一个实例来讲解。考虑数组 `a[5]`,需要获取 `a[3]` 的地址,有如下写法
1214+
说完理论,不如结合一个实例来讲解。考虑数组 `a[5]`,需要获取 `a[3]` 的地址,有如下两种写法
12151215
12161216
```llvm
1217+
; 方法一
12171218
%1 = getelementptr [5 x i32], [5 x i32]* @a, i32 0, i32 3
12181219
1220+
; 方法二
12191221
%2 = getelementptr [5 x i32], [5 x i32]* @a, i32 0
12201222
%3 = getelementptr i32, i32* %2, i32 3
1221-
1222-
%3 = getelementptr i32, i32* @a, i32 3
12231223
```
12241224
1225+
当数组作为参数时,需要先将其转换为指针类型,即方法二中的第一条指令。在被调用的函数中,对于指针类型的参数,使用方法二中的第二条指令即可获取对应下标元素的地址。
1226+
12251227
### (2)数组定义与调用
12261228

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

1251-
当然,`zeroinitializer` 不是必须的,同学们完全可以一个个 `i32 0` 写进去,但对于一些很阴间的样例点,不用 `zeroinitializer` 可能会导致 **TLE** ,例如全局数组 `int a[1000];` ,不使用该指令就需要输出 **1000 次 i32 0**,必然导致 TLE,所以还是推荐同学们使用 `zeroinitializer`
1252-
12531253
对于局部数组,在定义的时候同样需要使用 `alloca` 指令,其存取指令同样采用 **load 和 store**,只是在此之前需要采用 `getelementptr` 获取数组内应位置的地址。
12541254

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

0 commit comments

Comments
 (0)