中间表示- 到达定义分析

news/2024/5/6 16:37:20/文章来源:https://blog.csdn.net/weixin_43844521/article/details/130030752

基本概念 

定义(def):对变量的赋值

使用(use):对变量值的读取

问题:能把上图中的y替换为3吗?如果能,这称之为“常量传播”优化。

该问题等价于,有哪些对变量y的定义能够到达语句a = y?

到达定义:对每个变量的使用点,有哪些定义可以到达?(即:该变量的值是在哪儿赋值的?)

如果赋值点有且只有一个,并且那个赋值点是一个常数的话,那么就可以做常量传播了。

所以,到达定义是一种程序分析,这种程序分析的结果就可以用来指导接下来我们做常量传播这种优化。再次印证了下面这张图。

接下来的问题是,如何用算法来做到达定义分析?

在此,我们引出数据流分析中非常重要的数学工具——数据流方程

数据流方程

注:d是这条定义的编号,x的变量(比如,右侧第一条定义[1: y = 3])

  • gen(产生集)这个集合中存放的是语句的编号,因为语句编号和语句是一一对应的(双射关系),所以可以理解为语句本身。例如,gen[1: y = 3] = {1},可将gen集合理解为当前的这条语句给出了一条什么定义,显然,如果它是一条定义的话,就生成自身。从4向下走就可以见到4处定义了y(可在此直观的体会一下生成的含义)。
  • kill集合,例如kill[4: y = 6] = defs[y] - {4} = {1, 5},可以理解为,这些集合都被当前的定义点杀死,只能看到此处(定义点)的4,其他的y所在的序号都被屏蔽了。
  • defs[x]是x的所有定义点,例如defs[y] = {1, 4, 5}。

下面再解释一下数据流方程

给每条语句定义两个集合in[S]和out[S],in集合表示在进入语句S之前,有哪些定义是可以见到的(有多少语句是可达的,可到达这儿的),out集合表示经过S之后有哪些语句是可以出去,继续到达下一条的。

结合下面这个例子,看看每个定义点处的in和out集合都是什么 

in[1] = {∅},out[1] = {1}

in[2] = {1},out[2] = {2,1}

in[3] = {2, 1},out[3] = {3,2,1}

in[4] = {3,2,1},out[4] = {4,3,2}

注意,在此处到达5的定义是{4,3,2}没有1,意味着y在1处的定义是不可能到达5的,因为它总是会被4覆盖掉。

结合前面的内容,如果要做常数传播优化的话,结合到达定义分析就比较容易做了,而且这个到达定义分析是足够精确的,它会忽略掉那些不会到达的定义,只会算静态看可以到达的。

可以这么理解数据流方程:数据在程序中流动的过程中,每一点都标注了若干数据。

从数据流方程到算法

算法:对一个基本块的到达定义算法

  • 输入:基本块中所有的语句
  • 输出:对每个语句计算in和out两个集合
List_t stms;    // 一个基本块中的所有语句
set = {};       // 临时变量,记录当前语句s的in集合
reaching_definition()
{foreach (s ∈ stms){in[s] = set;out[s] = gen[s] ∪ (in[s] - kill[s]);set = out[s];}
}

对于一般的控制流图

以上讨论的都是基本块内的,那么对于一般的控制流图呢?我们可以写以下两条前向数据流方程,注意,我们只是对刚才基本块内的方程做了推广。

前向数据流方程

从数据流方程到不动点算法

算法:对所有基本块的到达定义算法

  • 输入:基本块中所有的语句
  • 输出:对每个语句计算in和out两个集合
List_t stms;    // 所有基本块中的所有语句
set = {};       // 临时变量,记录当前语句s的in集合
reaching_definition()
{while (some set in[] or out[] is still changing){foreach (s ∈ stms){foreach (predecessor p of s)set ∪= out[p];in[s] = set;out[s] = gen[s] ∪ (in[s] - kill[s]);}}
}

一开始6条语句上的每个in和out集合都初始化为空集,先来看第一遍运算,从第一号语句开始,它的in集合为初始的空集,out集合通过计算为{1},这样的计算前后对比,out集合发生了变化。同理,我们继续计算2号语句,它的in等于前驱元素out的并,我们可以看到有两条边进入2号,所以它有两个前驱元素(1号和5号),1号的out集合为{1},5号的out集合为{},所以2号语句的in集合为{1},2号语句的out通过计算为{1, 2},同理可以依次计算3-6。

为什么叫不动点呢?因为这其中包含一个循环,从5号语句出发又重新回到了2号语句这边,这样的循环导致对这里面到达定义的分析不可能一遍完成,正如我们在上图第一个表格中看到的,第一遍初始值与第二遍计算结束后,有些集合(确切的来说是2n - 1个集合)都发生了变化,只有第一个集合没有变,所以只要有集合还在发生变化,那么我们就要进行下一轮,如果还有变化的话,就继续进行下一轮,直到到达一个不动点为止。

该不动点算法为什么可以终止?因为对于一个确定的程序而言,每个基本语句的in,out集是固定且有限的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283893.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OPNET Modeler 例程——创建一个移动无线网络

文章目录一、例程概述二、创建天线模型三、创建指向处理器四、创建节点模型1.发射机节点模型2.干扰发射机节点模型3.收信机节点模型五、创建网络模型六、收集统计量并运行仿真七、查看仿真结果总结一、例程概述 OPNET 无线模块支持地面和卫星无线系统的构建。在此例程中将构建…

【C++】基础篇

C基础篇什么是C命名空间命名空间的三种使用方式C的输入和输出缺省参数缺省参数分类函数重载引用引用的使用场景常引用指针和引用的区别auto关键字auto使用细则auto不能推导的场景基于范围的for循环范围for的使用条件指针空值nullptr什么是C 1982年,Bjarne Stroustr…

微服务+springcloud+springcloud alibaba学习笔记【Eureka服务注册中心】(3/9)

Eureka服务注册中心 3/91、服务注册与发现1.1 什么是服务治理:1.2 什么是服务注册与发现:1.3 Eureka服务注册与发现2、单机版eureka2.1 创建module2.2改pom依赖2.3写yml配置文件:2.4主启动类2.5 修改服务提供者 cloud-provider-payment8001 模块&#xf…

GFS的卷类型与集群实验文档

GlusterFS 支持七种卷,即分布式卷、条带卷、复制卷、分布式条带卷、分布式复制卷、条带复制卷和分布式条带复制卷。我们常用的有前五种,今天我们就来看一看这五种卷都有什么优缺点。 一、分布式卷(Distribute volume) 文件通过 H…

【模型复现】resnet,使用net.add_module()的方法构建模型。小小的改进大大的影响,何大神思路很奇妙,基础很扎实

从经验来看,网络的深度对模型的性能至关重要,当增加网络层数后,网络可以进行更加复杂的特征模式的提取,所以当模型更深时理论上可以取得更好的结果。但是更深的网络其性能一定会更好吗?实验发现深度网络出现了退化问题…

python玄阶斗技--tkinter事件

在前一篇文章中,我们已经了解是tkinter的一些标签的使用,但一个GUI程序除了让别人看到,还要有一些交互操作,实现人机交互的方法我们称为事件,通过事件分为:鼠标事件,键盘事件和窗口事件。接下来…

Neo4j初学者使用记录(在更)

打开Neo4j cmdR 输入neo4j console 浏览器中输入框中网址:http://localhost:7474/即可打开 新建库 服务器版需要更改配置文件,若neo4j服务正在运行,则按Ctrlc,停止该服务。 配置完后,再重新开启服务,刷新…

如何利用ventoy制作Linux to go (把deepin放到U盘里)

准备工作 最新版本 – 深度科技社区 (deepin.org) deepin镜像官方下载即可 Releases ventoy/vtoyboot GitHub ventoy启动插件选择1.0.29版本 Downloads – Oracle VM VirtualBox VirtualBox虚拟机官网 ventoy下载 VentoyRelease (lanzoui.com) 选择下载1.0.29版本 vento…

第五十八章 线段树(一)

第五十八章 线段树(一)一、树状数组的缺陷二、线段树的作用三、线段树的基本构成1、节点定义2、线段树的结构四、线段树的重要函数1、构造线段树——bulid函数2、查询区间——query函数3、单点修改——modify函数五、例题一、树状数组的缺陷 在前面两个…

对于电商行业来讲,真正决定它的并不是规模,而是载体

纵然是在现在这样的情况之下,我们依然无法用「格局已定」来形容和阐述现在的电商市场格局。这一点,我们可以从以抖音、快手为代表的电商新势力的崛起当中,看出一丝端倪。对于电商行业来讲,真正决定它的并不是规模,而是…

Dart中的异步

一 事件循环 flutter 就是运行在一个root isolate 中 程序只要运行起来,就有一个事件循环一直在运行 ,直至程序退出。 EventLoop 先从mrcro 对列中取任务,取完任务再去 event 队列中取任务。队列任务是FIFO。 二 认识Future abstract clas…

[JavaEE]----Spring03

文章目录Spring_day031,AOP简介1.1 什么是AOP?1.2 AOP作用1.3 AOP核心概念2,AOP入门案例2.1 需求分析2.2 思路分析2.3 环境准备2.4 AOP实现步骤步骤1:添加依赖步骤2:定义接口与实现类步骤3:定义通知类和通知步骤4:定义切入点步骤5:制作切面步骤6:将通知…

C++内存管理(new和delete)

目录 1. new/delete操作内置类型 2. new和delete操作自定义类型 3. operator new与operator delete函数 4 .new和delete的实现原理 1 .内置类型 2 .自定义类型 new的原理 delete的原理 new T[N]的原理 delete[]的原理 5. 定位new表达式(placement-new) 6. malloc/f…

使用Process Explorer和Clumsy定位软件高CPU占用问题

目录 1、问题描述 2、使用Process Explorer初步找到CPU占用高的原因 3、使用Clumsy工具在公司内网环境复现了问题 4、根据Process Explorer中的函数调用堆栈,分析源码,最终找出了问题 5、总结 在排查项目客户的视频图像闪烁问题时,无意中…

Centos7安装部署Jenkins

Jenkins简介: Jenkins只是一个平台,真正运作的都是插件。这就是jenkins流行的原因,因为jenkins什么插件都有 Hudson是Jenkins的前身,是基于Java开发的一种持续集成工具,用于监控程序重复的工作,Hudson后来被…

JavaScript基础-02

常量(字面量):数字和字符串 常量也称之为“字面量”,是固定值,不可改变。看见什么,它就是什么。 常量有下面这几种: 数字常量(数值常量)字符串常量布尔常量自定义常量…

【MATLAB数学建模编程实战】Kmeans算法编程及算法的简单原理

欢迎关注,本专栏主要更新MATLAB仿真、界面、基础编程、画图、算法、矩阵处理等操作,拥有丰富的实例练习代码,欢迎订阅该专栏!(等该专栏建设成熟后将开始收费,快快上车吧~~) 【MATLAB数学建模编…

[LeetCode周赛复盘] 第 340 场周赛20230409

[LeetCode周赛复盘] 第 340 场周赛20230409 一、本周周赛总结二、 6361. 对角线上的质数1. 题目描述2. 思路分析3. 代码实现三、6360. 等值距离和1. 题目描述2. 思路分析3. 代码实现四、6359. 最小化数对的最大差值1. 题目描述2. 思路分析3. 代码实现五、 6353. 网格图中最少访…

ROS实践06 自定义消息类型

文章目录运行环境:思路:1.1 定义.msg文件1)功能包下新建 msg 目录,添加文件 Person.msg2)修改package.xml3)修改CMakeLists.txt2.1 自定义消息调用(C)1)编译后修改includePath2)发布方实现2.1修改CMakeLists.txt2.3运行…

【OpenCV-Python】cvui 之 trackbar

CVUI 之 trackbar cvui::trackbar() 渲染一个 trackbar, 可以左右拖动或点击对数字进行增加或减少的调整。 不使用离散间隔 使用离散间隔 Python import numpy as np import cv2 import cvuidef trackbar_test():WINDOW_NAME Trackbar-Test# 创建画布frame np.z…