前言
研究意义:程序需要花费大部分时间来执行循环,改进循环效率的优化有很大的影响。
程序分析:如果一个程序不包含任何循环,我们只需要对程序进行一趟扫描就可以得到数据流问题的答案,
对于流图中存在的循环,下面介绍几个概念:支配结点、深度优先排序、回边、图的深度和可归约性。
本篇对寻找循环以及迭代式数据流分析的速度进行阐述。
基本术语
- 支配结点:如果每一条从流图的入口结点到结点n的路径都经过节点d,成为d支配n,记为d dom n。
注意:在这个定义下,结点支配自己本身。
- 前进边:从一个节点m到达m在树中的一个真后代节点的边。
- 回退边:有些边从一个结点m到达m在树中的某个祖先(包括m本身),这些边称为后退边。
- 回边:一条边a->b,它的头b支配了它的尾a。
- 可归约性:如果一个流图的任何深度优先生成树中所有后退边都是回边。
- 支配结点树:在树中,入口结点就是根结点,并且每个结点d值支配它在树中的后代结点。
可归约性起源于作用于流图的若干种变换,这些变换将子图蜕化成单个结点,因此连续地"归约"流图到更简单的若干子图。如果一系列的这种转换能够最终地将流图归约为单个结点,就称这个流图是可归约的。
支配结点
深度优先排序
1.树的遍历
用于描述属性的求值过程,一个树的遍历从根结点开始,并按照某个顺序访问树的各个结点。
2.深度优先生成树(Depth-First Spanning Tree,DFST)
一次深度优先遍历从根结点开始,递归地按照任意顺序访问各个结点的子结点,并不一定要按照从左到右的顺序遍历。
深度优先,这种遍历总数尽可能地访问一个节点尚未被访问的子节点,它总是尽可能地访问离根节点最远的结点(即最深的结点)。
一次深度优先过程中的搜索路线形成了一个深度优先生成树。
3.深度优先排序
首先访问一个结点,然后遍历该结点的最右子结点,再遍历这个子结点左边的子结点(在同一层的结点)。
对于一颗深度优先生成树,深度优先排序的顺序和后序遍历序列相反。
首先构建深度优先生成树,在为流图构造生成树之前,可以选择把一个节点的哪个后继作为它在树中的最右子结点,再选择哪个后继结点是下一个子结点。
流图的深度
给定一个流图的深度优先生成树,该流图的深度是各条无环路径上的后退边数目中的最大值。
自然循环
编译器的分析可以假设某些初始条件在循环的每次迭代的开头成立,
自然循环通过两个重要的性质来定义:
1)它必须具有一个唯一的入口结点,称为循环头。这个入口结点支配了循环中的所有节点。
2)必然存在一条进入循环头的回边,否则控制流就不可能从"循环"中直接回到循环头。
给定一个回边n->d,我们定义该边的自然循环是d加上那些不经过d就能够到达n的结点的集合,结点d是这个循环的循环头。
因为一个可归约的流图中的所有后退边都是回边,我们可以把每条后退边和一个自然循环关联起来。
如果我们只把自然循环当做"循环",可以得到以下的性质:除非两个循环具有相同的循环头,否则它们要么是分离的,要么嵌套在另一个中。
ps:项目中处理的循环基本上是嵌套的循环,这里我们先不考虑带有分支判断的循环。