Dfi:一个面向大规模代码库的过程间价值流分析框架

2023-05-26 发布 0条评论

解决痛点

由于内存和运行时需求较高,目前的价值流计算方法无法扩展到大型代码库。

价值流分析

价值流分析是数据流分析的一个子集,它有助于静态地分析变量和内存块等程序结构之间的依赖关系。它支持许多关键的程序分析技术,这些技术被广泛用于编译器优化和寻找安全漏洞:指向分析、空指针分析和污点分析。为了有效地操作,这类技术通常需要精确的价值流信息,这些信息具有上下文和流敏感以及过程间性。” <span class="citation" data-citation="%7B%22citationItems%22%3A%5B%7B%22uris%22%3A%5B%22http%3A%2F%2Fzotero.org%2Fusers%2F8438660%2Fitems%2FMZGEWCFE%22%5D%2C%22locator%22%3A%221%22%7D%5D%2C%22properties%22%3A%7B%7D%7D" ztype="zcitation">(<span class="citation-item"><a href="zotero://select/library/items/MZGEWCFE">Hsu 等, 2022, p. 1</a></span>)</span>

创新点

DFI 设计与实现

\<img alt="" data-attachment-key="77NCYF4F" width="514" height="271" src="attachments/77NCYF4F.png" ztype="zimage">

DFI主要包括两个主要组成部分:

首先,分析引擎基于客户端提供的价值流映射信息计算得到运行过程内的DFT间隔;\<img alt="" data-attachment-key="SZWRTZMH" width="516" height="273" src="attachments/SZWRTZMH.png" ztype="zimage">

其次,过程内的价值流被传递到它们的调用者以支持过程间查询;

最后,客户端分析将受到流和上下文敏感的价值流结果,以解决其领域特定的作用

预处理:修改了两个操作

dfi.store:将更新的存储量用不同的标记存储,使得可以用跟踪标量值相同的方法跟踪强更新的内存依赖\<img alt="" data-attachment-key="8IEUGXVH" width="501" height="420" src="attachments/8IEUGXVH.png" ztype="zimage">dfi.call:为捕获输出参数传输的价值流,DFI将llvm.call替换为dfi.call\<img alt="" data-attachment-key="8DA727AH" width="504" height="148" src="attachments/8DA727AH.png" ztype="zimage">\<img alt="" data-attachment-key="ABUX5456" width="540" height="193" src="attachments/ABUX5456.png" ztype="zimage">

程序内(运行过程内)分析:

价值流分析可以归结为一个图可达性问题,其中每个顶点都是程序点上的数据流事实,通过判断两个顶点的可达性来解决价值流分析问题。

核心思想:对于一个给定的价值流分析问题,如果程序中的每一个相关操作都被注释为DFT区间,那么可以通过比较任意两个操作在几乎恒定时间内的区间来判断它们之间的可达性。\<img alt="" data-attachment-key="WYCD2LKH" width="508" height="220" src="attachments/WYCD2LKH.png" ztype="zimage">
为了演示这个概念,图3给出了一个MLIR函数,其中的值用DFT区间进行了标注。例如,值% p和% 1的区间分别为⟨0,5和⟨1,4。这些区间标注在由SSA定义-引用图衍生的生成树上,由从单个SSA值定义到其用途的边组成。假设对图3进行污点分析,% p为污点值。为了判断返回值% 3是否被污染,只需检查其区间⟨2,3 “是否被% p⟨0,5 “所包含。在这种情况下,由于⟨0,5⋅⊇⟨2,3⋅根据我们在2.3节的定义,返回值是污点。事实上,% 1和% 3都是污点,因为它们的区间都在⟨0,5 “的子树内。另一方面,间隔为⟨7,8的% 0不被污染,因为它位于以⟨6,9为根的不同DFT子树中。”
为了计算图3所示的树和相关区间,客户端分析自定义了2.3节中介绍的遍历机制。首先,对于每个函数,客户端分析选择一组根顶点开始遍历。注意,每个函数中的遍历时间戳总是从零开始。其次,对于函数中的每个顶点,通过客户端分析提供一个局部转移函数来指示离开的顶点进行下一次访问。在图3污点分析的背景下,客户端分析选择% a和% p作为遍历根。对于局部传递函数,每类运算的规则如图4所示。以dfi . store规则为例,其中仅当存储值% v被污染时,结果指针% q才被污染。它有效地停止了从% p到% q的DFT遍历,但允许从% v到% q的路径。” <span class="citation" data-citation="%7B%22citationItems%22%3A%5B%7B%22uris%22%3A%5B%22http%3A%2F%2Fzotero.org%2Fusers%2F8438660%2Fitems%2FMZGEWCFE%22%5D%2C%22locator%22%3A%225%22%7D%5D%2C%22properties%22%3A%7B%7D%7D" ztype="zcitation">(<span class="citation-item"><a href="zotero://select/library/items/MZGEWCFE">Hsu 等, 2022, p. 5</a></span>)</span>

DEF-USE的非树边

非树边的存在抑制了图的可达性在一般SSA的DEF-USE图上的应用,因此,减少非树边是一件很必要的事情。

\<img alt="" data-attachment-key="IN4VK3R6" width="473" height="97" src="attachments/IN4VK3R6.png" ztype="zimage">

\<img alt="" data-attachment-key="IS7HBY7K" width="546" height="250" src="attachments/IS7HBY7K.png" ztype="zimage">

采用反转图:可以有效避免多参数情况下的函数产生的非树边问题。
增广DFT区间图的可达性:在遇到非树边时复制区间,以此可以使用两个区间之间相似的包含关系确定它们的可达性

采用的算法是使用一个基于工作表的算法,递归地改变总结传播给其调用者,直到达到一个固定点:\<img alt="" data-attachment-key="9UUVB3YA" width="548" height="283" src="attachments/9UUVB3YA.png" ztype="zimage">
在算法1中,GetV FSummary ( f )返回函数f的Sf;PropagateSummary( Sf , c)在调用函数c中执行前面介绍的带有被调用者值-流摘要Sf的两阶段传播。 <span class="citation" data-citation="%7B%22citationItems%22%3A%5B%7B%22uris%22%3A%5B%22http%3A%2F%2Fzotero.org%2Fusers%2F8438660%2Fitems%2FMZGEWCFE%22%5D%2C%22locator%22%3A%227%22%7D%5D%2C%22properties%22%3A%7B%7D%7D" ztype="zcitation">(<span class="citation-item"><a href="zotero://select/library/items/MZGEWCFE">Hsu 等, 2022, p. 7</a></span>)</span>

可达功能的摘要:将传播过程扩展到一个可达函数的摘要。

通过区间集Π vb⊇Π va确定两个值va和vb在同一函数中的可达性,可以计算具有流量和上下文敏感性的程序间的价值流。在这一部分中,将这种能力推广到任意函数中的va和vb。
一个可达函数摘要Ψ ( ε )提供了一个从端点ε到可通行端点集合的映射。端点ε<sup>i</sup><sub>f</sub>表示函数f的第i个参数。

对于函数所有的所有参数,Ψ被反复传播到它的所有调用者,并与它们的摘要值合并,直到达到一个固定值,即所有可达函数的摘要值都不发生变化为止。

对于某个可达函数摘要,可以执行一个两阶段的过程来回答不同函数中的va->vb是否是可达的:

  1. 计算集合\<img alt="" data-attachment-key="W8I72BH7" width="328" height="34" src="attachments/W8I72BH7.png" ztype="zimage"> 检查对于任意的索引j是否包含函数g的端点ε

    <sup>j</sup>

    <sub>g</sub>

  2. 只有当前端点ε

    <sup>j</sup>

    <sub>g </sub>

    可以达到vb时,va才能达到vb,即:\<img alt="" data-attachment-key="V46LADJM" width="203" height="33" src="attachments/V46LADJM.png" ztype="zimage">

评估

回答两个问题:

所有实验在10分钟内完成,使用的物理内存不超过4.5 GB。

发表评论