RA, 寄存器分配

本文详细介绍了寄存器分配的四个步骤:计算D-U链、构建Web、构造冲突图和修剪冲突图。通过数据流分析计算LiveOut和LiveIn,建立变量的活跃性,并在冲突图中进行优化,确保寄存器的有效分配。最后讨论了PRF和CRF的分配策略,包括如何处理溢出和选择最优分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

寄存器分配

1. 如何计算D-U链

(1) 首先遍历整个routine,保存所有def值;
问题:
你如何去保存这些def值呢?要保证能快速的得到每个def值,因为每一 个 def 值不仅仅只包含dst寄存器号,还包括这条指令,以及其它信息。

解答之一:
最快速的查找算法,就是hash算法。在我们这里通过构建一个含有256个元素的hash表,hash[regNo & (256-1)] = defIndex;对于hash冲突的处理方法是,在def值的结构中存放一个变量,用来保存冲突的defIndex.

比如:

r1 = r2 + r3;//defIndex = x;
r1 = r1 * r4;//defIndex = x + 1;
很显然,此时两次def的r1的hash值是一样的,但两次def的defIndex是不一样的, 假定第一次的defIndex = x, 那么(pDefs + defIndex) ->hashNextDefIndex = x + 1;其实可以把这理解为链表的形式处理hash冲突,但冲突不是在hash表上处理的而已。

(2) 自顶向下计算每个Basic Block的LiveOut def值,这里的LiveOut def值表示在离开当前block后还可能活跃的def值。然后通过数据流分析,得到每个Basic Block的LiveIn def值。
问题:
如何计算?

解答之一 :
根据routine中的def值的数目,来定义一个长度为32bit倍数的变量(假定变量名字为FlowFunction),每一位用来表示对应的defIndex, 为1,表示活跃, 为0, 表示不活跃。
1) 分block扫描所有指令,在每一个block里,对有dst的指令,将FlowFunction变量的对应位置为1;如果出现多次定义一个变量的情况,则只会把最后一次的defIndex置为1,也就是在每次扫描的过程中,在最后一次def的时候,会把前一次的def clear 掉;这样每个Basic Block的FlowFunction变量的值就得到了;
2) 上一步只是得到每一个Block中的LiveOut def变量,因为在整个routine中block是有数据流关系的,如果当前Block有predecessor Block,则当前Block的LiveIn def变量 = 所有predecessor Block的LiveOut的或运算。
比如:
LiveIn(Block 5) = LiveOut(Block 3) | LiveOut(Block 4);
这里写图片描述
(3) 计算完每个Basic Block的LiveIn def值后,自顶向下扫描每个Block。首先检查每条指令的src, 然后根据src可以得到其所有的defIndex, 如果这个defIndex在LiveIn中,那么就将这个Usage添加到这个def中。然后检查这条指令的dst,这个dst是否已经在LiveIn中,如果是,则将 旧的defIndex从LiveIn中删掉,否则将这个dst的defIndex添加到LiveIn中。(此时的LiveIn已经不是原来的LiveIn,只能说初始值是原来的LiveIn吧)。
问题:为什么要计算LiveIn的def变量?如下图所示,如果不计算第1个block的LiveOut def值,那么在其successor block中use变量i就不知道来自于哪个def了
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值