编译器优化那些事儿(5):寄存器分配

本文深入探讨了编译器优化中的寄存器分配问题,包括活跃变量分析、图着色算法以及线性扫描算法。通过实例展示了如何计算变量的活跃区间,构建干涉图并进行着色,同时讨论了寄存器溢出和合并策略。此外,还介绍了LLVM中的寄存器分配实现,并对比了不同分配算法的性能。
  1. 引言
  2. 概念介绍
  3. 活跃变量分析与图着色算法
  4. 线性扫描
  5. llvm中实现
  6. 参考

引言

本文首先会简述用到的基本概念,然后借助一个例子介绍活跃变量分析和图着色算法,最后会介绍线性扫描算法及其llvm12中实现。

概念介绍

在介绍算法之前,我们回顾下基本概念:

  • |X|:X的度数,(无向图中)节点的邻居个数。
  • CFG:控制流图。
  • successor:本文指CFG中基本块的后继。
  • 四元式:(op,result,arg1,arg2),比如常见的a=b+c就可以看作四元式(+,a,b,c)。
  • SSA(Static Single Assignment):静态单赋值。
  • use/def:举个例子,对于指令n: c <- c+b来说 use[n]={c,b},def[n]={c}。
  • live-in:当以下任一条件满足时,则称变量a在节点n中是live-in的,写作a∈in[n]。节点n本文中代表指令。
  • live-out: 变量a在节点n的任一后继的live-in集合中。写作a∈out[n]KaTeX parse error: Undefined control sequence: \out at position 34: …(out[n]-def[n])\̲o̲u̲t̲[n] = in[s_1]\c…
  • 干涉:在某一时刻,两个变量在同一live-in集合中。
  • RIG(Register Interfere Graph): 无向图,其点集和边集构成如下:
  • 节点:变量
  • 边:如果两节点存在干涉,那么这两节点之间就有一条干涉边
  • k-着色:给定无向图G=(V,E),其中V为顶点集合,E为边集合。将V分为k个组,每组中没有相邻顶点,可称该图G是k着色的。当然可着色前提下,k越小越好。需要注意的是,我们后续的算法会作用在最普通的四元式上,而不是SSA。在介绍寄存器分配算法之前,我们需要活跃变量分析来构建干涉图。

活跃变量分析与图着色算法

活跃变量分析

简单来说,就是计算每个点上有哪些变量被使用。

算法描述如下[1]:

input: CFG = (N, E, Entry, Exit)
begin
// init
for each basic block B in CFG
    in[B] = ∅
// iterate
do{
    for each basic block B other than Exit{
        out[B] = ∪(in[s]),for all successors s of B
        in[B] = use[B]∪(out[B]-def[B])
    }
}until all in[] do't change

活跃变量分析还有孪生兄弟叫Reaching Definitions,不过实现功能类似,不再赘述。

举个例子:对图1的代码进行活跃变量分析

图1,参考[2]画的

可以得到每个点的活跃变量如图2所示:

图2

过程呢?限于篇幅,仅仅计算第一轮指令1的结果,剩余部分读者可自行计算。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

openEuler社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值