静态程序分析01

活跃变量分析

活跃变量分析(Live Variable Analysis)是编译器优化和静态分析的一项重要技术,用于确定在程序的每个程序点(通常是每个基本块的出口)上哪些变量仍然是“活跃”的,也就是在程序执行到该点时仍然会被使用。

活跃变量分析通常用于以下两个主要领域:
寄存器分配:在编译器优化中,了解哪些变量在每个程序点上仍然是活跃的,有助于进行寄存器分配。只有活跃的变量需要存储在寄存器中,因此可以在寄存器之间有效地分配变量,以最大程度地减少内存访问。
死代码消除:在静态分析中,了解哪些变量在程序中不再被使用,有助于进行死代码消除。通过删除不再使用的变量和相关代码,可以减小程序的大小并提高执行效率。

java样例

class Assign {

    int assign(int a, int b, int c) {
        int d = a + b;
        b = d;
        c = a;
        return b;
    }
}

分析结果
-------------------- <Assign: void <init>()> (livevar) --------------------
[0@L1] invokespecial %this.<java.lang.Object: void <init>()>(); []
[1@L1] return; []

-------------------- <Assign: int assign(int,int,int)> (livevar) --------------------
[0@L4] d = a + b; [a, d]
[1@L5] b = d; [a, b]
[2@L6] c = a; [b]
[3@L7] return b; []

活跃变量算法设计

方向:为了确定某BB后var是否live,只需从exit bb往前判断该var是否use而非def
边界条件:因为活跃算法分析是backward,边界条件为exit点处In、Out集合为空
初始化: 为每个BB的In、Out集合初始化为空
交汇处理:Out[S1] = ∪ In[S1后继]
转换函数 : In[B] = UseB ∪ (Out[B] - DefB)

请添加图片描述

数据结构设计与算法实现

数据结构:

  1. 集合,用来进行交、并操作。实现如下:
public class SetFact<E> {

    protected final Set<E> set;

    public SetFact(Collection<E> c) {
        set = Sets.newHybridSet(c);
    }

    public SetFact() {
        this(Collections.emptySet());
    }

    /**
     * @return true if this set contains the specified element, otherwise false.
     */
    public boolean contains(E e) {
        return set.contains(e);
    }

    /**
     * Adds an element to this fact.
     *
     * @return true if this fact changed as a result of the call, otherwise false.
     */
    public boolean add(E e) {
        return set.add(e);
    }

    /**
     * Removes an element from this fact.
     *
     * @return true if an element was removed as a result of the call, otherwise false.
     */
    public boolean remove(E e) {
        return set.remove(e);
    }

    /**
     * Removes all the elements of this fact that satisfy the given predicate.
     *
     * @return true if any elements were removed as a result of the call,
     * otherwise false.
     */
    public boolean removeIf(Predicate<E> filter) {
        return set.removeIf(filter);
    }

    /**
     * Unions other fact into this fact.
     *
     * @return true if this fact changed as a result of the call, otherwise false.
     */
    public boolean union(SetFact<E> other) {
        return set.addAll(other.set);
    }

    /**
     * @return a new fact which is the union of this and other facts.
     */
    public SetFact<E> unionWith(SetFact<E> other) {
        SetFact<E> result = copy();
        result.union(other);
        return result;
    }

    /**
     * Intersects this fact with other fact.
     *
     * @return true if this fact changed as a result of the call, otherwise false.
     */
    public boolean intersect(SetFact<E> other) {
        return set.retainAll(other.set);
    }

    /**
     * @return a new fact which is the intersection of this and other facts.
     */
    public SetFact<E> intersectWith(SetFact<E> other) {
        SetFact<E> result = copy();
        result.intersect(other);
        return result;
    }

    /**
     * Sets the content of this set to the same as other set.
     */
    public void set(SetFact<E> other) {
        clear();
        union(other);
    }

    /**
     * Creates and returns a copy of this fact.
     */
    public SetFact<E> copy() {
        return new SetFact<>(this.set);
    }

    /**
     * Clears all content in this fact.
     */
    public void clear() {
        set.clear();
    }

    public boolean isEmpty() {
        return set.isEmpty();
    }

    public Stream<E> stream() {
        return set.stream();
    }

    public int size() {
        return set.size();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof SetFact<?> that)) {
            return false;
        }
        return set.equals(that.set);
    }

    @Override
    public int hashCode() {
        return set.hashCode();
    }

    @Override
    public String toString() {
        return CollectionUtils.toString(set);
    }
}
  1. 结果数据流图,保存cfg上每一个BB对应的In、Out集合。实现如下:
public class DataflowResult<Node, Fact> implements NodeResult<Node, Fact> {

    private final Map<Node, Fact> inFacts = new LinkedHashMap<>();

    private final Map<Node, Fact> outFacts = new LinkedHashMap<>();

    /**
     * @return the flowing-in fact of given node.
     */
    @Override
    public Fact getInFact(Node node) {
        return inFacts.get(node);
    }

    /**
     * Associates a data-flow fact with a node as its flowing-in fact.
     */
    public void setInFact(Node node, Fact fact) {
        inFacts.put(node, fact);
    }

    /**
     * @return the flowing-out fact of given node.
     */
    @Override
    public Fact getOutFact(Node node) {
        return outFacts.get(node);
    }

    /**
     * Associates a data-flow fact with a node as its flowing-out fact.
     */
    public void setOutFact(Node node, Fact fact) {
        outFacts.put(node, fact);
    }
}
  1. 单IR语句数据结构。实现如下:
public interface Stmt extends Indexable {

    /**
     * @return the index of this Stmt in the container IR.
     */
    @Override
    int getIndex();

    void setIndex(int index);

    /**
     * @return the line number of this Stmt in the original source file.
     * If the line number is unavailable, return -1.
     */
    int getLineNumber();

    void setLineNumber(int lineNumber);

    /**
     * @return the (optional) left-value expression defined in this Stmt.
     * In Tai-e IR, each Stmt can define at most one expression.
     */
    Optional<LValue> getDef();

    /**
     * @return a list of right-value expressions used in this Stmt.
     */
    List<RValue> getUses();

    /**
     * @return true if execution after this statement could continue at
     * the following statement, otherwise false.
     */
    boolean canFallThrough();

    <T> T accept(StmtVisitor<T> visitor);
}

活跃变量算法实现

  1. 单BB处的LiveVariableAnalysis。实现如下:
public class LiveVariableAnalysis extends
        AbstractDataflowAnalysis<Stmt, SetFact<Var>> {

    public static final String ID = "livevar";

    public LiveVariableAnalysis(AnalysisConfig config) {
        super(config);
    }

    /**
     * backward分析
     * @return
     */
    @Override
    public boolean isForward() {
        return false;
    }

    /**
     * 边界条件初始化
     * In[exit] = ∅
     * @param cfg
     * @return
     */
    @Override
    public SetFact<Var> newBoundaryFact(CFG<Stmt> cfg) {
        return new SetFact<>();
    }

    /**
     * 基本块初始化
     * for(each BB b|exit)
     *  In[B] = ∅
     * @return
     */
    @Override
    public SetFact<Var> newInitialFact() {

        return new SetFact<>();
    }

    /**
     * meet 操作
     * 将fact集合并入target集合
     * out[S1] = in[S2] ∪ in[S3]
     * @param fact in[successor]
     * @param target out[node]
     */
    @Override
    public void meetInto(SetFact<Var> fact, SetFact<Var> target) {
        target.union(fact);
    }

    /**
     * transfer函数操作单条语句
     * In[B] = UseB ∪ (Out[B] - DefB)
     * Rvalue 包括 var、literal、unaryexp、binaryexp
     * 这里只考虑var
     * @param stmt
     * @param in
     * @param out
     * @return
     */
    @Override
    public boolean transferNode(Stmt stmt, SetFact<Var> in, SetFact<Var> out) {
        boolean flag;
        SetFact<Var> tmpOut = out.copy();

        Optional<LValue> def = stmt.getDef();
        List<RValue> use = stmt.getUses();
        //判断左值是否存在
        //左值只有一个
        if(def.isPresent() && def.get() instanceof Var defVal){
            tmpOut.remove(defVal);
        }

//        flag = in.union(tmpOut);
//        for(RValue rvalue : use){
//            if(rvalue instanceof Var useVal){
//                flag |= in.add(useVal);
//            }
//        }
        for(RValue rv : use){
            if(rv instanceof Var useVal)
                tmpOut.add(useVal);
        }

        flag = (!tmpOut.equals(in));
        in.clear();
        in.set(tmpOut);

        return flag;
    }
}
  1. 迭代求解器。实现如下:
public abstract class Solver<Node, Fact> {

    protected final DataflowAnalysis<Node, Fact> analysis;

    protected Solver(DataflowAnalysis<Node, Fact> analysis) {
        this.analysis = analysis;
    }

    /**
     * Static factory method to create a new solver for given analysis.
     */
    public static <Node, Fact> Solver<Node, Fact> makeSolver(
            DataflowAnalysis<Node, Fact> analysis) {
        return new IterativeSolver<>(analysis);
    }

    /**
     * Starts this solver on the given CFG.
     *
     * @param cfg control-flow graph where the analysis is performed on
     * @return the analysis result
     */
    public DataflowResult<Node, Fact> solve(CFG<Node> cfg) {
        DataflowResult<Node, Fact> result = initialize(cfg);
        doSolve(cfg, result);
        return result;
    }

    /**
     * Creates and initializes a new data-flow result for given CFG.
     *
     * @return the initialized data-flow result
     */
    private DataflowResult<Node, Fact> initialize(CFG<Node> cfg) {
        DataflowResult<Node, Fact> result = new DataflowResult<>();
        if (analysis.isForward()) {
            initializeForward(cfg, result);
        } else {
            initializeBackward(cfg, result);
        }
        return result;
    }

    protected void initializeForward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
        throw new UnsupportedOperationException();
    }

    protected void initializeBackward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
        result.setInFact(cfg.getExit(), this.analysis.newBoundaryFact(cfg));
        result.setOutFact(cfg.getExit(), this.analysis.newBoundaryFact(cfg));

        for(Node node : cfg){
            if(cfg.isExit(node))
                continue;
            result.setInFact(node, this.analysis.newInitialFact());
            result.setOutFact(node, this.analysis.newInitialFact());
        }
    }

    /**
     * Solves the data-flow problem for given CFG.
     */
    private void doSolve(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
        if (analysis.isForward()) {
            doSolveForward(cfg, result);
        } else {
            doSolveBackward(cfg, result);
        }
    }

    protected abstract void doSolveForward(CFG<Node> cfg, DataflowResult<Node, Fact> result);

    protected abstract void doSolveBackward(CFG<Node> cfg, DataflowResult<Node, Fact> result);
}
class IterativeSolver<Node, Fact> extends Solver<Node, Fact> {

    public IterativeSolver(DataflowAnalysis<Node, Fact> analysis) {
        super(analysis);
    }

    @Override
    protected void doSolveForward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
        throw new UnsupportedOperationException();
    }

    /**
     * result存分析结果
     * cfg为控制流图
     * @param cfg
     * @param result
     */
    @Override
    protected void doSolveBackward(CFG<Node> cfg, DataflowResult<Node, Fact> result) {
        boolean flag = true;
        while(flag){
            flag = false;
            for(Node node : cfg){
                for(Node succ : cfg.getSuccsOf(node))
                    this.analysis.meetInto(result.getInFact(succ), result.getOutFact(node));
                if(this.analysis.transferNode(node, result.getInFact(node), result.getOutFact(node))){
                    flag = true;
                }
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值