到达定义数据流问题的特例

问题描述

| 达到定义的问题是数据流分析中最基本的问题之一。给定一个包含变量定义和用途的控制流程图,问题将导致计算哪些变量定义可以达到特定用途。 例如,考虑流程图:
                    ____________
                 1:|   x <- ... |
                    ------------
                     |            \\
                     |              __________
                     |           2:| x <- ... |
                     |              -----------
                     |            /
                    ____________    
                 3:|  ... <- x  |
                    ------------
可以通过块1或块2中的定义来达到在块3中使用变量x的目的。 用于计算哪些定义可以使用的算法是经典的数据流问题。使用Dragon编译器手册(新版)中的符号,定义数据流问题如下: 域:定义集(例如{x <-..,...}) 方向:前进 传递函数:fb(x)= gen(B)U(x-kill(B))其中gen(B)是块B生成的定义集,而kill(B)是块B杀死的定义集 边界:OUT [ENTRY] = {},即没有定义流进入函数 Meet运算符:U(union),即流到一个块的定义是前一个块之外的定义的并集。 方程:OUT [B] = fb(IN [B]),IN [B] = U(P in pred)OUT [P] 初始化:OUT [B] = {} 但是,并非所有定义都相同。例如,块1中的定义可能永远不会在块3中使用,因为它可能会被块2中的定义杀死。另一方面,块2中的定义如果执行,将保留其值,直到在块中使用它为止。 3。 我想找到一种用法的到达定义,在从定义到用法的任何路径上都没有致命的定义。我的问题是是否存在类似的数据流问题(可能是传播等)。如何通过数据流分析解决它。 我确实有解决此问题的可能方法,但是如果已经存在解决方案,我就不想重新发明轮子。     

解决方法

像这样更改问题定义: Meet运算符:∩(相交),即流到一个块的定义是前一个块中定义的交集。 公式:OUT [B] = fb(IN [B]),             IN [B] =∩(P in pred)OUT [P]     ,这是我解决问题的方法。这可能不是最有效的方法,但我相信它是有效的。我将把这个问题称为保留定义的问题。首先,我计算到达定义。我在以位集表示的定义集上使用迭代数据流算法。 为此,我首先需要计算每个块的gen(B)和kill(B)。这些是分别由每个块生成和终止的定义。请注意,kill(B)是实际kill(B)的超集,因为我不知道什么定义以及从哪个块中真正杀死了这些数据,因为此时我不考虑数据流。 应用到达定义后,我为控制流程图中的每个块设置了REACH_IN(B)和REACH_OUT(B)设置。我知道保留的定义是到达定义的子集。为了计算它们,我需要找出从程序进入每个块以来从未被杀死的定义。我将这些集称为非杀死集,并且将提供一种算法来为图中的每个块计算NO_KILL_IN(B)和NO_KILL_OUT(B)。这里是关于数据流分析的算法。 域:定义集(例如{x <-..,...}) 方向:前进 传递函数:fb(x)= x-(kill(B)∩REACH_IN(B))其中kill(B)是阻止B杀死的定义集,而REACH_IN(B)是流入B的定义集。 边界:NO_KILL_OUT [ENTRY] = U(通用集),即所有定义都不会从函数输入中被杀死 Meet运算符:∩(交集),即,如果未在任何先前程序段中取消定义,则不取消定义。 公式:NO_KILL_OUT [B] = fb(IN [B]),NO_KILL_IN [B] =∩(P in pred)NO_KILL_OUT [P] 初始化:NO_KILL_OUT [B] = U 请注意,在tranfer函数中,我们计算kill(B)∩REACH_IN(B),这是在块B中被杀死的一组实际定义。如果不使用它,我们将过于悲观。算法计算每个块之前和之后哪些定义不能被杀死,而无需考虑是否已生成。为了计算保留的定义,我们简单地执行交集: PRESERVE_IN(B)= REACH_IN(B)∩NO_KILL_IN(B) PRESERVE_OUT(B)= REACH_OUT(B)∩NO_KILL_OUT(B)     ,您可能想看一下时间逻辑,而计算树逻辑很适合在控制流图中定义路径上的属性。本文显示了CTL中数据流属性的一些示例: 通过时间逻辑证明编译器优化的正确性     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...