Search in sources :

Example 1 with UnitMap

use of soot.util.UnitMap in project soot by Sable.

the class BusyCodeMotion method internalTransform.

/**
 * performs the busy code motion.
 */
protected void internalTransform(Body b, String phaseName, Map<String, String> opts) {
    BCMOptions options = new BCMOptions(opts);
    HashMap<EquivalentValue, Local> expToHelper = new HashMap<EquivalentValue, Local>();
    Chain<Unit> unitChain = b.getUnits();
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     performing Busy Code Motion...");
    CriticalEdgeRemover.v().transform(b, phaseName + ".cer");
    UnitGraph graph = new BriefUnitGraph(b);
    /* map each unit to its RHS. only take binary expressions */
    Map<Unit, EquivalentValue> unitToEquivRhs = new UnitMap<EquivalentValue>(b, graph.size() + 1, 0.7f) {

        protected EquivalentValue mapTo(Unit unit) {
            Value tmp = SootFilter.noInvokeRhs(unit);
            Value tmp2 = SootFilter.binop(tmp);
            if (tmp2 == null)
                tmp2 = SootFilter.concreteRef(tmp);
            return SootFilter.equiVal(tmp2);
        }
    };
    /* same as before, but without exception-throwing expressions */
    Map<Unit, EquivalentValue> unitToNoExceptionEquivRhs = new UnitMap<EquivalentValue>(b, graph.size() + 1, 0.7f) {

        protected EquivalentValue mapTo(Unit unit) {
            Value tmp = SootFilter.binopRhs(unit);
            tmp = SootFilter.noExceptionThrowing(tmp);
            return SootFilter.equiVal(tmp);
        }
    };
    /* if a more precise sideeffect-tester comes out, please change it here! */
    SideEffectTester sideEffect;
    if (Scene.v().hasCallGraph() && !options.naive_side_effect()) {
        sideEffect = new PASideEffectTester();
    } else {
        sideEffect = new NaiveSideEffectTester();
    }
    sideEffect.newMethod(b.getMethod());
    UpSafetyAnalysis upSafe = new UpSafetyAnalysis(graph, unitToEquivRhs, sideEffect);
    DownSafetyAnalysis downSafe = new DownSafetyAnalysis(graph, unitToNoExceptionEquivRhs, sideEffect);
    EarliestnessComputation earliest = new EarliestnessComputation(graph, upSafe, downSafe, sideEffect);
    LocalCreation localCreation = new LocalCreation(b.getLocals(), PREFIX);
    Iterator<Unit> unitIt = unitChain.snapshotIterator();
    {
        /* insert the computations at the earliest positions */
        while (unitIt.hasNext()) {
            Unit currentUnit = unitIt.next();
            for (EquivalentValue equiVal : earliest.getFlowBefore(currentUnit)) {
                // Value exp = equiVal.getValue();
                /* get the unic helper-name for this expression */
                Local helper = expToHelper.get(equiVal);
                // the beginning of the method
                if (currentUnit instanceof IdentityStmt)
                    currentUnit = getFirstNonIdentityStmt(b);
                if (helper == null) {
                    helper = localCreation.newLocal(equiVal.getType());
                    expToHelper.put(equiVal, helper);
                }
                /* insert a new Assignment-stmt before the currentUnit */
                Value insertValue = Jimple.cloneIfNecessary(equiVal.getValue());
                Unit firstComp = Jimple.v().newAssignStmt(helper, insertValue);
                unitChain.insertBefore(firstComp, currentUnit);
            }
        }
    }
    {
        /* replace old computations by the helper-vars */
        unitIt = unitChain.iterator();
        while (unitIt.hasNext()) {
            Unit currentUnit = unitIt.next();
            EquivalentValue rhs = unitToEquivRhs.get(currentUnit);
            if (rhs != null) {
                Local helper = expToHelper.get(rhs);
                if (helper != null)
                    ((AssignStmt) currentUnit).setRightOp(helper);
            }
        }
    }
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     Busy Code Motion done!");
}
Also used : EquivalentValue(soot.EquivalentValue) PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) SideEffectTester(soot.SideEffectTester) NaiveSideEffectTester(soot.jimple.NaiveSideEffectTester) BCMOptions(soot.options.BCMOptions) HashMap(java.util.HashMap) PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) LocalCreation(soot.jimple.toolkits.scalar.LocalCreation) AssignStmt(soot.jimple.AssignStmt) Local(soot.Local) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) Unit(soot.Unit) UnitGraph(soot.toolkits.graph.UnitGraph) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) EquivalentValue(soot.EquivalentValue) Value(soot.Value) NaiveSideEffectTester(soot.jimple.NaiveSideEffectTester) UnitMap(soot.util.UnitMap) IdentityStmt(soot.jimple.IdentityStmt)

Aggregations

HashMap (java.util.HashMap)1 EquivalentValue (soot.EquivalentValue)1 Local (soot.Local)1 SideEffectTester (soot.SideEffectTester)1 Unit (soot.Unit)1 Value (soot.Value)1 AssignStmt (soot.jimple.AssignStmt)1 IdentityStmt (soot.jimple.IdentityStmt)1 NaiveSideEffectTester (soot.jimple.NaiveSideEffectTester)1 PASideEffectTester (soot.jimple.toolkits.pointer.PASideEffectTester)1 LocalCreation (soot.jimple.toolkits.scalar.LocalCreation)1 BCMOptions (soot.options.BCMOptions)1 BriefUnitGraph (soot.toolkits.graph.BriefUnitGraph)1 UnitGraph (soot.toolkits.graph.UnitGraph)1 UnitMap (soot.util.UnitMap)1