静态程序分析03

死代码消除

通过活跃变量分析和常量传播进行死代码消除优化

算法实现

注意不同stmt的判定

    /**
     * 死代码检测
     * 检测不可达代码和无用赋值
     * 1. 不可达代码:控制流不可达代码和分支不可达代码
     * 1.1 控制流不可达代码:返回语句之后的代码
     * 1.2 分支不可达:
     * 1.2.1 if语句中如果条件值为常量则其中一个分支不会走到
     * 1.2.2 case语句中如果case为常量则其他case分支不可达
     * 2. 无用赋值
     * 一个局部变量在一条语句中被赋值,但没有被该语句后的语句读取,这样的变量为无用变量
     * 但是所有x = exp语句都不能去除,因为等号右边语句可能带有副作用
     * @param ir
     * @return
     */
    @Override
    public Set<Stmt> analyze(IR ir) {
        // obtain CFG
        CFG<Stmt> cfg = ir.getResult(CFGBuilder.ID);
        // obtain result of constant propagation
        DataflowResult<Stmt, CPFact> constants =
                ir.getResult(ConstantPropagation.ID);
        // obtain result of live variable analysis
        DataflowResult<Stmt, SetFact<Var>> liveVars =
                ir.getResult(LiveVariableAnalysis.ID);
        // keep statements (dead code) sorted in the resulting set
        Set<Stmt> deadCode = new TreeSet<>(Comparator.comparing(Stmt::getIndex));

        Set<Stmt> reachableCode = new TreeSet<>(Comparator.comparing(Stmt::getIndex));
        Queue<Stmt> workList = new ArrayDeque<>();
        workList.add(cfg.getEntry());
        while(!workList.isEmpty()){
            Stmt stmt = workList.poll();

            if(reachableCode.contains(stmt))
                continue;

            reachableCode.add(stmt);
            Set<Edge<Stmt>> edges = cfg.getOutEdgesOf(stmt);
            // if statement
            // 计算if表达式
            // 根据if结果加入边
            if(stmt instanceof If ifStmt){
                Value value = ConstantPropagation.evaluate(ifStmt.getCondition(), constants.getInFact(ifStmt));
//                if(!value.isConstant()){
//                    workList.addAll(cfg.getSuccsOf(stmt));
//                    continue;
//                }
                for(Edge<Stmt> stmtEdge : edges){
                    if((value.getConstant() >= 1 && stmtEdge.getKind() == Edge.Kind.IF_TRUE) ||
                            (value.getConstant() <= 0 && stmtEdge.getKind() == Edge.Kind.IF_FALSE)){
                        workList.add(stmtEdge.getTarget());
                        break;
                    }
                }
            }
            // switch statement
            // 常量传播获得case的值
            // 将相应的边加入
            else if (stmt instanceof SwitchStmt switchStmt) {
                Value value = constants.getResult(switchStmt).get(switchStmt.getVar());
                int caseResult = value.getConstant();
                boolean matched = false;
                for(Edge<Stmt> stmtEdge : edges){
                    if(stmtEdge.getKind() == Edge.Kind.SWITCH_CASE && stmtEdge.getCaseValue() == caseResult){
                        workList.add(stmtEdge.getTarget());
                        matched = true;
                        break;
                    }
                }
                if(!matched){
                    workList.add(switchStmt.getDefaultTarget());
                }
            }
            // Assign statement:x = exp
            // 查看x是否活跃
            // exp 是否有影响
            else if (stmt instanceof AssignStmt<?,?> assignStmt) {
                workList.addAll(cfg.getSuccsOf(stmt));
                if(!hasNoSideEffect(assignStmt.getRValue()))
                    continue;

                if(assignStmt.getLValue() instanceof Var LValue){
                    SetFact<Var> varSetFact = liveVars.getResult(stmt);
                    if(!varSetFact.contains(LValue))
                        reachableCode.remove(assignStmt);
                }
            }
            // control flow: fall through
            else{
                workList.addAll(cfg.getSuccsOf(stmt));
            }
        }

        for(Stmt stmt : cfg){
            if(!reachableCode.contains(stmt))
                deadCode.add(stmt);
        }
        // Your task is to recognize dead code in ir and add it to deadCode
        return deadCode;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值