LLVM理论篇之编译器中端

LLVM编译器中端解析

1、简述

编译器中端所进行的工作是在前端的基础上,先将整个语法树转换为中间代码,再通过进行一系列优化遍(pass)对程序生成的中间代码(IR)进行优化,包括中间代码生成和中间代码优化两个部分。

2、中间代码生成

在讲中间代码生成之前,要先明白中间代码是什么。

LLVM中间表示有三种格式:

(1)在内存中的编译中间语言;

(2)硬盘上存储的二进制中间语言,以.bc文件保存

(3)可读的中间代码格式,以.ll文件保存

LLVM 中间代码结构包括四个部分:

(1)模块(Module)是LLVM IR的顶层容器,对应于编译器前端的每个翻译单元。每个模块由目标机器信息、全局符号(全局变量和函数)及元信息组成。

(2)函数(Function)就是编译语言中的函数,包括函数签名和若干个基本块,函数内的第一个本块叫入口基本块(entry)。

(3)基本块(BasicBlock)是一组顺序执行的指令集合,只有一个入口和一个出口,非头尾指令执行时不会违背顺序跳转到其他指令上去。每个基本块最后一条指令一般是跳转指令(跳转到其它基本块上),函数内最后一个基本块的最后一条指令是函数返回指令。

(4)指令(Instruction)是LLVM IR中的最小可执行单元。

3、中间代码优化

代码优化阶段的任务是对中间代码进行变换或者改造,目的是使生成的代码更为高效。LLVM中优化器opt可对中间代码实施优化,常见的有删除公共子表达式、循环优化、复写传播、无用赋值的删除等。

-O优化选项用以控制编译器在对程序编译时的优化级别,常用的有-O0、-O1、-O2、-O3、-Ofast,不同优化选项对应的优化选项:

选项

所包含的优化选项

-O1

在-O0的基础上添加-instcombine、-simplifycfg、-loops、-loop-unroll等

-O2

在-O1的基础上添加-inline、-fvectorize、-fslp-vectorize等

-O3

在-O2的基础上添加-aggressive-instcombine、-callsite-splitting、-domtree等

-Ofast

在-O3的基础上添加-fno-signed-zeros、-freciprocal-math、-ffp-contract=fast、-menable-unsafe-fp-math、-menable-no-nans、-menable-no-infs、-mreassociate、-fno-trapping-math、-ffast-math、-ffinite-math-only等。

4、示例讲解

编写示例文件test.c,内容如下:

#include <stdio.h>

#define N 1024

int main()

{

  int a,b,c;

  a = 2;

  b = 4;

  c = a + b * 3;

  print("%d\n", c);

  return 0;

}

这是一个简单计算的程序,用来演示中间代码生成的过程。通过中间代码生成的相关编译选项,来生成LLVM的该文件的中间代码。

(1)源代码生成.ll形式的可读中间代码

使用命令

clang -emit-llvm -S test.c -o test.ll

得到结果test.ll

(2)源代码生成.bc形式的字节码

使用命令:

clang -emit-llvm -c test.c -o test.bc

生成的.bc文件是不可读的字节码,这里就不展示了

(3)中间代码的转换

将.ll文件转成.bc文件:

llvm-as test.ll -o test.bc

将.bc文件转成.ll文件:

llvm-dis test.bc -o test.ll

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值