代码移动
所谓代码移动就是对于代码中的不变计算,将其移动到循环之外,在进入循环之前就进行计算。因此代码移动就涉及到两方面的计算:
- 循环不变计算的检测
- 代码外提
循环不变计算检测算法
输入:循环L,每个三地址指令的ud链。
输出:L的循环不变计算语句。
方法
- 将下面这样的语句标记为“不变”:语句的运算分量或者是常数,或者其所有定值点都在循环L外部。
- 重复执行步骤(3),直到某次没有新的语句可标记为“不变”为止。
- 将下面这样的语句标记为“不变”:先前没有被标记过,且所有运
算分量或者是将下面这样的语句标记为“不变”:先前没有被标记过,且所有运算分量或者是常数,或者其所有定值点都在循环L外部 ,或者只有一个到达定值,该定值是循环中已经被标记为“不变”的语句。
代码外提
前置首结点 (preheader)
循环不变计算将被移至首结点之前,为此创建一个称为前置首结点的新块。前置首结点的唯一后继是首结点,并且原来从循环L外到达L首结点的边都改成进入前置首结点。从循环L里面到达首结点的边不变。
循环不变计算语句s: x = y + z移动的条件
- s所在的基本块是循环所有出口结点(有后继结点在循环外的结点)的支配结点
- 循环中没有其它语句对x赋值
- 循环中对x的引用仅由s到达
代码移动算法
输入:循环L、ud链、支配结点信息
输出:修改后的循环
方法:
- 寻找循环不变计算。
- 对于步骤(1) 中找到的每个循环不变计算,检查是否满足上面的三个条件。
- 按照循环不变计算找出的次序,把所找到的满足上述条件的循环不变计算外提到前置首结点中。如果循环不变计算有分量在循环中定值,只有将定值点外提后,该循环不变计算才可以外提。