8 LLVM-IR-(表达式的翻译与控制流的翻译)

8 LLVM-IR-(表达式的翻译与控制流的翻译)

父节点需要为子节点传递跳转指令的目标标签,以继承属性的形式传递给子节点

如上面的例子中,B 是条件语句需要生成跳转指令,但 B 不知道该跳转到什么标签,如果 B 是 true,应该跳转到 S1 标签,而 S1 是 S 才知道的,因此由 S 传递给 B;如果 B 是 false,那么应该跳转到 S 后面的语句的标签,但 S 也不知道到底是什么标签,但 P 知道,因此需要由 p 传递给 B。

image-20230108204811522

1. 表达式的中间代码翻译

image-20230108204931249

2. 数组引用的中间代码翻译

image-20230108205535816

继承属性得到数组类型的宽度

image-20230108210004925

image-20230108210108328

image-20230108210132405

image-20230108210832591

a[i] 在上面中间代码中的 i64 0 是因为, %2 是 [2 × [3 × i32]]* 类型的,因此虽然它指向的是数组首地址,但因为类型是整个数组,因此直接对 %2 加上偏移量 i 会偏移 i 个数组大小的长度,这不是我们想要的,因此需要先降一层,先取偏移量为 0,得到指向同一个地址,但是类型是 [3 × i32]* 类型的,对这个类型进行我们想要的 i 偏移才是正确的

3. 控制流语句与布尔表达式的中间代码翻译

if 语句

image-20230108211354248

image-20230108211603964

image-20230108212423027

image-20230108212415996

上面例子中的代码生成的中间代码就是

1
2
3
4
5
6
7
8
p.code:
s.code:
goto L1 // 对应if(true)
L1: // : 都是标签label
goto L0 // 对应if(false),因此assign没有被执行,直接到L0
L3:
assign // 对应assign
L0:

if-else语句

image-20230108212933325

image-20230108214001284

上面例子中的代码生成的中间代码就是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
p.code:
s.code:
goto L1 // 对应if(true)
L1: // : 都是标签label
s1.code:
goto L3 // 对应if(true)
L3:
assign
goto L0 // 第二层if-true结束,跳转到第二层if-else后面
L4:
assign
goto L0 // 第一层if-true结束,跳转到第一层if-else后面
L2:
assign // 对应第一层else的assign
L0:

while 语句

image-20230108215139970

image-20230110191037687

上面例子中的代码生成的中间代码就是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
p.code:
s.code:
begin:
goto L1 // 对应while(true)
L1: // : 都是标签label
s1.code:
goto L4 // 对应if(false)
L3:
assign
goto begin // 跳到while循环开始
L4:
assign
goto begin // 跳到while循环开始
L0:

image-20230110191439360

4. 布尔表达式的中间代码翻译

image-20230110193632692

image-20230110194827798

image-20230110195006411

短路求值,当 B1 是 true 时,那么直接就是 B 是 true 了,当 B1 是 false,才跳转到 B2 的 code

image-20230110195133929

image-20230110195337123

关系运算符表达式:≥,>等

例子:

image-20230110201224607

image-20230110201234027

  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
  • Copyrights © 2022-2024 zzb
  • RZ
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信