您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
数据流分析应用
 
作者:bsauce
  1779  次浏览      18
2020-7-3 
 
编辑推荐:

本文重点介绍了理解3种数据流分析的含义,如何设计类似的算法,如何优化,理解种数据流分析的共性与区别,理解种数据流分析的共性与区别。
本文来自简书,由火龙果软件Anna编辑、推荐。

1.数据流分析总览

may analysis:输出可能正确的信息(需做over-approximation优化,才能成为Safe-approximation安全的近似,可以有误报-completeness),注意大多数静态分析都是may analysis

must analysis:输出必须正确的信息(需做under-approximation优化,才能成为Safe-approximation安全的近似,可以有漏报-soundness)

Nodes (BBs/statements)、Edges (control flows)、CFG (a program)

例如:

application-specific Data <- abstraction (+/-/0)

Nodes <- Transfer function

Edges <- Control-flow handling

不同的数据流分析 有 不同的数据抽象表达 和 不同的安全近似策略,如 不同的 转换规则 和 控制流处理。

2-1-数据流分析总览.png

2.预备知识

输入/输出状态:程序执行前/执行后的状态(本质就是抽象表达的数据的状态,如变量的状态)。

数据流分析的结果:最终得到,每一个程序点对应一个数据流值(data-flow value),表示该点所有可能程序状态的一个抽象。例如,我只关心x、y的值,我就用抽象来表示x、y所有可能的值的集合(输入/输出的值域/约束),就代表了该程序点的程序状态。

Forward Analysis前向分析:按程序执行顺序的分析。OUT[s]=fs(IN[s]),s-statement

Backward Analysis反向分析:逆向分析。IN[s]=fs(OUT[s])

控制流约束:约束求解做的事情,推断计算输入到输出,或反向分析。

2-2-控制流约束.png

3.Reaching Definitions Analysis (may analysis)

问题定义:给变量v一个定义d(赋值),存在一条路径使得程序点p能够到达q,且在这个过程中不能改变v的赋值。

应用举例:检测未定义的变量,若v可达p且v没有被定义,则为未定义的变量。

抽象表示:设程序有n条赋值语句,用n位向量来表示能reach与不能reach。

(1)公式分析

什么是definition? D: v = x op y 类似于赋值。

Transfer Function:OUT[B] = genB U (IN[B] - killB) ——怎么理解,就是基于转换规则而得到。

解释:基本块B的输出 = 块B内的所有变量v的定义(赋值/修改)语句 U (块B的输入 - 程序中其它所有定义了变量v的语句)。本质就是本块与前驱修改变量的语句 作用之和(去掉前驱的重复修改语句)。

Control Flow:IN[B] = Up a_predecesso_of_B Out[P] ——怎么理解,就是基于控制流而得到。

解释:基本块B的输入 = 块B所有前驱块P的输出的并集。注意,所有前驱块意味着只要有一条路径能够到达块B,就是它的前驱,包括条件跳转与无条件跳转。

2-3-1-Reaching_Definition.png

(2)算法

目的:输入CFG,计算好每个基本块的killB(程序中其它块中定义了变量v的语句)和genB(块B内的所有变量v的定义语句),输出每个基本块的IN[B]和OUT[B]。

方法:首先所有基本块的OUT[B]初始化为空。遍历每一个基本块B,按以上两个公式计算块B的IN[B]和OUT[B],只要这次遍历时有某个块的OUT[B]发生变化,则重新遍历一次(因为程序中有循环存在,只要某块的OUT[B]变了,就意味着后继块的IN[B]变了)。

2-3-2-可达性分析算法.png

(3)实例:

抽象表示:设程序有n条赋值语句,用n位向量来表示能reach与不能reach。

说明:红色-第1次遍历;蓝色-第2次遍历;绿色-第3次遍历。

结果:3次遍历之后,每个基本块的OUT[B]都不再变化。

2-3-3遍历实例.png

现在,我们可以回想一下,数据流分析的目标是,最后得到了,每个程序点关联一个数据流值(该点所有可能的程序状态的一个抽象表示,也就是这个n位向量)。在这个过程中,我们对个基本块,不断利用基于转换规则的语义(也就是transfer functions,构成基本块的语句集)-OUT[B]、控制流的约束-IN[B],最终得到一个稳定的安全的近似约束集。

(4)算法会停止吗?

OUT[B] = genB U (IN[B] - killB)

大致理解:genB和 killB是不变的,只有IN[B]在变化,所以说OUT[B]只会增加不会减少,n向量长度是有限的,所以最终肯定会停止。具体涉及到不动点证明,后续课程会讲解。

4.Live Variables Analysis (may analysis)

问题定义:某程序点p处的变量v,从p开始到exit块的CFG中是否有某条路径用到了v,如果用到了v,则v在p点为live,否则为dead。其中有一个隐含条件,在点p和引用点之间不能重定义v。

2-4-1-live_variables定义.png

应用场景:可用于寄存器分配,如果寄存器满了,就需要替换掉不会被用到的变量。

抽象表示:程序中的n个变量用长度为n bit的向量来表示,对应bit为1,则该变量为live,反之为0则为dead。

(1)公式分析

Control Flow:OUT[B] = US a_successor_of_BIN[S]

理解:我们是前向分析,只要有一条子路是live,父节点就是live。

Transfer Function:IN[B] = useB U (OUT[B] - defB)

理解:IN[B] = 本块中use出现在define之前的变量 U (OUT[B]出口的live情况 - 本块中出现了define的变量)。define指的是定义/赋值。

特例分析:如以下图所示,第4种情况,v=v-1,实际上use出现在define之前,v是使用的。

2-4-2-公式推导.png

(2)算法

目的:输入CFG,计算好每个基本块中的defB(重定义)和useB(出现在重定义之前的使用)。输出每个基本块的IN[B]和OUT[B]。

方法:首先初始化每个基本块的IN[B]为空集。遍历每一个基本块B,按以上两个公式计算块B的OUT[B]和IN[B],只要这次遍历时有某个块的IN[B]发生变化,则重新遍历一次(因为有循环,只要某块的IN[B]变了,就意味前驱块的OUT[B]变了)。

问题:遍历基本块的顺序有要求吗? 没有要求,但是会影响遍历的次数。

2-4-3-live_variables算法.png

初始化规律:一般情况下,may analysis 全部初始化为空,must analysis全部初始化为all。

(3)实例

抽象表示:程序中的n个变量用长度为n bit的向量来表示,对应bit为1,则该变量为live,反之为0则为dead。

说明:从下往上遍历基本块,黑色-初始化;红色-第1次;蓝色-第2次;绿色-第3次。

结果:3次遍历后,IN[B]不再变化,遍历结束。

2-4-4-算法运行示例.png

5.Available Expressions Analysis (must analysis)

问题定义:程序点p处的表达式x op y可用需满足2个条件,一是从entry到p点必须经过x op y,二是最后一次使用x op y之后,没有重定义操作数x、y。(如果重定义了x 或 y,如x = a op2 b,则原来的表达式x op y中的x或y就会被替代)。

应用场景:用于优化,检测全局公共子表达式。

抽象表示:程序中的n个表达式,用长度为n bit的向量来表示,1表示可用,0表示不可用。

说明:属于forward分析。

(1)公式分析

Transfer Function:OUT[B] = genB U (IN[B] - killB)

理解:genB—基本块B中所有新的表达式(并且在这个表达式之后,不能对表达式中出现的变量进行重定义)-->加入到OUT;killB—从IN中删除变量被重新定义的表达式。

Control Flow:IN[B] = P a_predecessor_of_B OUT[P]

理解:从entry到p点的所有路径都必须经过该表达式。

2-5-1-可用表达式定义.png

问题:该分析为什么属于must analysis呢?因为我们允许有漏报,不能有误报,比如以上示例中,改为x=3,去掉 b=e16*x,该公式会把该表达式识别为不可用。但事实是可用的,因为把x=3替换到表达式中并不影响该表达式的形式。这里虽然漏报了,但是不影响程序分析结果的正确性。

(2)算法

目的:输入CFG,提前计算好genB和killB。

方法:首先将OUT[entry]初始化为空,所有基本块的OUT[B]初始化为1...1。遍历每一个基本块B,按以上两个公式计算块B的IN[B]和OUT[B],只要这次遍历时有某个块的OUT[B]发生变化,则重新遍历一次(因为有循环,只要某块的OUT[B]变了,就意味后继块的IN[B]变了)。

2-5-2-可用表达式算法.png

(3)实例

抽象表示:程序中的n个表达式,用长度为n bit的向量来表示,1表示可用,0表示不可用。

说明:黑色-初始化;红色-第1次;蓝色-第2次。

结果:2次遍历后,OUT[B]不再变化,遍历结束。

2-5-3-算法运行示例.png

6.三种分析技术对比

问题:怎样判断是May还是Must?

Reaching Definitions表示只要从赋值语句到点p存在1条路径,则为reaching,结果不一定正确;Live Variables表示只要从点p到Exit存在1条路径使用了变量v,则为live,结果不一定正确;Available Expressions表示从Entry到点p的每一条路径都经过了该表达式,则为available,结果肯定正确。

 

   
1779 次浏览       18
相关文章

基于EA的数据库建模
数据流建模(EA指南)
“数据湖”:概念、特征、架构与案例
在线商城数据库系统设计 思路+效果
 
相关文档

Greenplum数据库基础培训
MySQL5.1性能优化方案
某电商数据中台架构实践
MySQL高扩展架构设计
相关课程

数据治理、数据架构及数据标准
MongoDB实战课程
并发、大容量、高性能数据库设计与优化
PostgreSQL数据库实战培训
最新课程计划
信息架构建模(基于UML+EA)3-21[北京]
软件架构设计师 3-21[北京]
图数据库与知识图谱 3-25[北京]
业务架构设计 4-11[北京]
SysML和EA系统设计与建模 4-22[北京]
DoDAF规范、模型与实例 5-23[北京]
 
最新文章
InfluxDB概念和基本操作
InfluxDB TSM存储引擎之数据写入
深度漫谈数据系统架构——Lambda architecture
Lambda架构实践
InfluxDB TSM存储引擎之数据读取
最新课程
Oracle数据库性能优化、架构设计和运行维护
并发、大容量、高性能数据库设计与优化
NoSQL数据库(原理、应用、最佳实践)
企业级Hadoop大数据处理最佳实践
Oracle数据库性能优化最佳实践
更多...   
成功案例
某金融公司 Mysql集群与性能优化
北京 并发、大容量、高性能数据库设计与优化
知名某信息通信公司 NoSQL缓存数据库技术
北京 oracle数据库SQL优化
中国移动 IaaS云平台-主流数据库及存储技术
更多...