理论教育 编译器设计之路:活跃变量分析实现

编译器设计之路:活跃变量分析实现

时间:2023-11-04 理论教育 版权反馈
【摘要】:简而言之,活跃变量分析的目的就是求出各基本块出口之后的活跃变量集。前面,已经详细讲述了有关活跃变量分析的基本思想及相关理论。在本小节中,将关注活跃变量分析算法的设计与实现。事实上,活跃变量分析算法就是利用数据流方程求解的过程。在例7-1中,应用迭代方式手工求解活跃变量的过程就是算法设计的基础。先来谈谈活跃变量分析的相关数据结构。在活跃变量分析中,主要涉及四个基于基本块的集合,即in、out、def、use。

编译器设计之路:活跃变量分析实现

活跃变量分析是数据流分析的另一个重要问题。简而言之,活跃变量分析的目的就是求出各基本块出口之后的活跃变量集。前面,已经详细讲述了有关活跃变量分析的基本思想及相关理论。在本小节中,将关注活跃变量分析算法的设计与实现。

事实上,活跃变量分析算法就是利用数据流方程求解的过程。在例7-1中,应用迭代方式手工求解活跃变量的过程就是算法设计的基础。读者不妨再次参阅例7-1详细的求解过程,可能更有助于理解算法设计的思想。

先来谈谈活跃变量分析的相关数据结构。由于算法的数据结构较少且比较简单,故笔者并没有为其单独设置章节。在活跃变量分析中,主要涉及四个基于基本块的集合,即in、out、def、use。为了节省空间且便于实现,通常使用位向量来描述这四个集合。在Neo Pascal中,它们是隶属于CBasicBlock类的,具体声明形式如下:

【声明7-8】

其中,Def、Use位向量是由先前的Def_Use_Analysis函数分析得到的,因此,这里就不必关注了。而本小节的目标就是基于流图计算InSet、OutSet位向量。下面,就来看看详细的算法实现。

程序7-5 DataFlowAnalysis.cpp

第4行:获取当前过程的基本块信息。

第7~15行:初始化各基本块的InSet、OutSet位向量为空集。

第16~36行:bChange为迭代结束的标志。在这个算法中,迭代结束的条件就是前后两次迭代的过程中,各基本块的InSet位向量都没有发生变化。实际上,这种情况表示迭代已经进入了稳定状态,而这个稳定状态就是所需要的最终结果,因此,就没有继续迭代的意义了。(www.daowen.com)

第18行:进入一次求解过程之前,重置bChange标志。若求解过程中没有改变bChange标志,则表示当前状态已稳定,迭代即可终止。

第19~35行:遍历各基本块,依次计算各基本块的InSet、OutSet。

第22~26行:计算当前基本块的OutSet,其依据就是如下数据流公式:

out[s]=Uin[i] (其中i是s的后继基本块)

第27~29行:计算当前基本块的InSet,其依据就是如下数据流公式:

in[s]_(out[s)-def(s])U use[s]

第30~34行:判断新求得的InSet与基本块的原InSet是否相等,若不相等,则使用新求得的InSet作为基本块的InSet,并置bChange为true,表示本次迭代过程中状态发生了变化,即未进入稳定状况,迭代不能终止。

虽然算法的规模很小,但是要深入理解其实现却并不容易。在分析代码的过程中,部分读者可能会觉得这个算法的逻辑比较晦涩。确实如此,在日常程序设计中,迭代的应用可能没有递归广泛,因此,对迭代算法的思想比较生疏也不足为奇。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈