首页 > 其他分享 >软件分析课程实验A1-活跃变量分析和迭代求解器

软件分析课程实验A1-活跃变量分析和迭代求解器

时间:2022-11-22 19:44:09浏览次数:67  
标签:分析 活跃 node 变量 迭代 A1 基本块 SetFact def

课程主页:https://tai-e.pascal-lab.net/lectures.html

数据流分析

数据流分析指的是一种用来获取有关数据如何沿着程序执行路径流动的相关技术,许多编译优化技术都依赖于数据流分析。

数据流分析有很多经典的应用,比如

  • 到达定值分析
  • 活跃变量分析
  • 可用表达式分析

活跃变量分析原理

活跃变量分析(Live Variable Analysis)是数据流分析的一个经典应用

活跃变量

对于变量\(x\)和程序点\(p\),如果在程序流图中沿着从\(p\)开始的某条路径会引用变量\(x\)在\(p\)点的值,则称变量\(x\)在点\(p\)是活跃(live)的,否则称变量\(x\)在点\(p\)是不活跃(dead)的

主要用途

  1. 删除无用赋值:如果在某点赋值,但是后面又不会用到的话,可以将该点的赋值删除
  2. 寄存器分配:如果寄存器都被占用,则当再次申请寄存器的时候,需要替换掉一些占用寄存器的变量。通过活跃变量分析,可以将不活跃变量所占用的寄存器空出来

符号定义

\(def_B, use_B, IN[B], OUT[B]\)

  • \(def_B\) : 赋值先于任何使用的变量的集合
  • \(use_B\): 使用先于任何赋值的变量的集合
  • \(IN[B], OUT[B]\): 分别表示在紧靠一个基本块\(B\)之前和之后的点上的活跃变量的集合

比如对于下面\(B_2\) 的基本块中,对于 \(i = i + 1;\) 这条语句可以拆分成\(t = i + 1; i = t;\)两条指令,所以对于变量\(i\)而言,其使用先于任何赋值,所以属于\(use_{B_2}\) 中的变量,不属于\(def_{B_2}\)中的变量。

另一个例子是,对于一个基本块中如果有两条指令:\(v=2; k = v;\) 则变量\(v\)的赋值先于其任何的使用,所以变量\(v\)属于\(def_B\),而不属于 \(use_B\)。

根据这些定义,\(use_B\)中的任何变量都必然被认为在基本块\(B\)的入口处是活跃的,而\(def_B\)中所有的变量在B的开头一定是不活跃的。

实际上,\(def_b\)中的成员“杀死了”某个变量可能从\(B\)开始成为活跃变量的任何机会

《编译原理 第二版》P390

算法原理

  • \(IN[EXIT] = \emptyset\) : 边界条件,表示程序出口处没有变量是活跃的
  • 然后对所有除了\(EXIT\) 之外的基本块 \(B\) 来说,首先初始化所有\(B\)为空集 \(IN[B] = \emptyset\),初始化之后对所有的\(B\)执行如下的转移函数
    • \(OUT[B] = \cup _{S是B的一个后继} IN[S]\) :一个变量在离开一个基本块的时候活跃,当且仅当它进入该基本块的某个后继时活跃
    • \(IN[B] = use_B \cup(OUT[B] - def_B)\) :一个变量进入基本块的时候活跃必须保证 ,要么在基本块中被赋值之前就使用了,要么在离开基本块的时候活跃并且没有对它重新赋值

A1实验分析

实验目标

本次作业需要实现一个活跃变量分析算法,抽象的算法如下图所示,具体而言,需要求出每个基本块的InFact值,里面包含该点所有的活跃变量。本次作业需要填空来完成下图的算法实现

需要注意:

  • 本次作业的每个基本块仅含有一条指令
  • 实验的结果最后存储在参数 DataflowResult<Node, Fact> result
  • 用到了Java的一些特性
    • Optional特性:isPresent() 和 get()的使用
    • 泛型特性

step1: 初始化基本块的 InFact和OutFact

pascal/taie/analysis/dataflow/analysis/LiveVariableAnalysis.java

 @Override
    public SetFact<Var> newBoundaryFact(CFG<Stmt> cfg) {
        // TODO - finish me
        // 返回边界节点的向量,backwards的边界节点是 exit节点
        return new SetFact<Var>();
    }

    @Override
    public SetFact<Var> newInitialFact() {  // 返回值就是 SetFact<Var>
        // TODO - finish me
        // 除了exit节点的其他节点初始化为空
        return new SetFact<Var>();
    }

    @Override
    public void meetInto(SetFact<Var> fact, SetFact<Var> target) { // 注意这里提示了,使用的是SetFact<Var>, 所以前面用的也都是Var
        // TODO - finish me
        // 并起来
        target.union(fact);
    }

pascal/taie/analysis/dataflow/solver/Solver.java

    protected void initializeBackward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
        // TODO - finish me
        // step1 将 exit节点的InFact置为空集
        result.setInFact(cfg.getExit(), analysis.newBoundaryFact(cfg));
        // step2 将 除了exit节点之外的其他节点的InFact和OutFact置为空集
        for (Node node : cfg.getNodes()) {
            if (cfg.isExit(node)) continue;
            result.setInFact(node, analysis.newInitialFact());
            // 将OutFact也置为空集
            result.setOutFact(node, analysis.newInitialFact());
        }
    }

step2: 实现迭代求解器

pascal/taie/analysis/dataflow/solver/IterativeSolver.java

    @Override
    protected void doSolveBackward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
        // TODO - finish me
        boolean changed = true;

        while (changed) {
            changed = false;

            for (Node node : cfg.getNodes()) {
                // 除了exit的Node,因为exitNode没有outFact
                if (cfg.isExit(node)) continue;
                // 求出OutFact
                for (Node succNode : cfg.getSuccsOf(node)) {
                    analysis.meetInto(result.getInFact(succNode), result.getOutFact(node));
                }
                // 使用outfact做转换,得到infact
                // 并且查看是否这个block的状态是否改变了
                if (analysis.transferNode(node, result.getInFact(node), result.getOutFact(node))) changed = true;
            }
        }
    }

step3: 实现转换函数

pascal/taie/analysis/dataflow/analysis/LiveVariableAnalysis.java

    @Override
    public boolean transferNode(Stmt stmt, SetFact<Var> in, SetFact<Var> out) {
        // TODO - finish me
        // 复制outFact,求出新的inFact
        SetFact<Var> newInFact = new SetFact<>();
        newInFact.union(out);
        // 求出新的inFact
        // outFact - def
        if (stmt.getDef().isPresent()) { // 先用isPresent再用get是optional的典型用法
            LValue def = stmt.getDef().get();
            if (def instanceof Var) {
                newInFact.remove((Var) def);
            }
        }
        // (outFact - def ) + use
        for (RValue use : stmt.getUses()) {
            if (use instanceof  Var) {
                newInFact.add((Var) use);
            }
        }
        // 判断inFact是否改变,并返回Boolean表示
        if (!newInFact.equals(in)) {
            in.set(newInFact);
            return true;
        }
        return false;
    }

参考资料

【编译原理,第二版】(龙书)

【超棒的博客,这个人是搞编译器的,他的博客可以看看】https://leiblog.wang/编译高级教程|学习笔记/#

【这个人的博客写了很多关于编译器优化的总结】https://www.jianshu.com/p/ebc1c72b881c

【活跃变量分析 & 常用表达式分析】https://liuyehcf.github.io/2017/11/24/编译原理-代码优化3/

【编译原理-哈工大,上面博客的课件都来自于此】https://www.bilibili.com/video/BV1zW411t7YE/?vd_source=ee07a5a150ae217eba28dd2c4bd5549b

【数据流分析应用总结】https://blog.csdn.net/weixin_43258309/article/details/104512206

标签:分析,活跃,node,变量,迭代,A1,基本块,SetFact,def
From: https://www.cnblogs.com/VanHa0101/p/16916233.html

相关文章

  • 混合开发Hybrid App的优劣分析
    纵观当前的移动开发,移动端实际的开发方式有三类:纯原生(NativeApp)、混合开发(HybirdApp)、网页应用(WebApp)。纯原生(NativeApp):是在Android、iOS等移动平台上利用提供的开发......
  • 瓴羊Quick BI工具,为数据分析人员带来帮助
    一个企业的数字化管理水平如何,和企业内部的发展情况都是密切相关的。为了企业的各部分发展可以进展到更好的状态,确实应该从多个角度来注意这些涉及到的情况。其中关注数据分......
  • SQL优化分析
    一、慢查询日志与分析什么是慢查询日志1MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query......
  • 对 Trojan.DL.Win32.Mnless.yxx / alg.exe 的一点分析
    对Trojan.DL.Win32.Mnless.yxx/alg.exe的一点分析endurer原创2008-02-21第1版就是Worm.Win32.Diskgen.gen/磁碟机也捎带广告?​javascript:void(0)​​中的捕获的一个......
  • java内存分析工具
    1、jmapmap一般可用于:jmap能够打印给定Java进程、核心文件或远程DEBUG服务器的共享对象内存映射或堆内存的详细信息内存监控分析对象内存怎么用?jmap相关命令:可通过jmap-......
  • java15源码-ArrayBlockingQueue
    一阻塞队列APIThrowsexceptionSpecialvalueBlocksTimesoutInsertadd(e)offer(e)put(e)offer(e,time,unit)Removeremove()poll()take()poll(......
  • Java FreeMarker模板引擎注入深入分析
    0x01前言最近和 F1or 大师傅一起挖洞的时候发现一处某CMSSSTI的0day,之前自己在复现jpress的一些漏洞的时候也发现了SSTI这个洞杀伤力之大。今天来好好系统学习......
  • 小新学Java10
    栈:先进后出队列:先进先出数组:查询快,增删慢 链表:查询慢、增删快 红黑树: 1、HashSet集合存储数据的结构(哈希表)  2、Set集合存储元素不重复的原理  3、E......
  • IPv6转换难点分析之一:国家监测指标-中科三方
    从IPv4过渡到IPv6就像是“打破一个旧世界,创建一个新世界”,注定要经历一个长期的过程,但终究会实现。一、IPv6过渡转换的障碍目前互联网上还是以IPv4设备为主,不可能迅速过......
  • 企业实际应用场景分析(2)
    dev开发环境使用者:程序员功能:程郡序员个人的办公电脑或项目的开发测试环境,部署开发软件,测试个人或项目整体的BUG的环境管理者:程序员测试环境使用者:QA测试工程师......