Search in sources :

Example 1 with PASideEffectTester

use of soot.jimple.toolkits.pointer.PASideEffectTester 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)

Example 2 with PASideEffectTester

use of soot.jimple.toolkits.pointer.PASideEffectTester in project soot by Sable.

the class CommonSubexpressionEliminator method internalTransform.

/**
 * Common subexpression eliminator.
 */
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    int counter = 0;
    // Sigh.  check for name collisions.
    Iterator<Local> localsIt = b.getLocals().iterator();
    Set<String> localNames = new HashSet<String>(b.getLocals().size());
    while (localsIt.hasNext()) {
        localNames.add((localsIt.next()).getName());
    }
    SideEffectTester sideEffect;
    if (Scene.v().hasCallGraph() && !PhaseOptions.getBoolean(options, "naive-side-effect")) {
        sideEffect = new PASideEffectTester();
    } else {
        sideEffect = new NaiveSideEffectTester();
    }
    sideEffect.newMethod(b.getMethod());
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     Eliminating common subexpressions " + (sideEffect instanceof NaiveSideEffectTester ? "(naively)" : "") + "...");
    // new SlowAvailableExpressions(b);
    AvailableExpressions ae = new FastAvailableExpressions(b, sideEffect);
    Chain<Unit> units = b.getUnits();
    Iterator<Unit> unitsIt = units.snapshotIterator();
    while (unitsIt.hasNext()) {
        Stmt s = (Stmt) unitsIt.next();
        if (s instanceof AssignStmt) {
            Chain availExprs = ae.getAvailableEquivsBefore(s);
            // logger.debug("availExprs: "+availExprs);
            Value v = ((AssignStmt) s).getRightOp();
            EquivalentValue ev = new EquivalentValue(v);
            if (availExprs.contains(ev)) {
                // now we need to track down the containing stmt.
                List availPairs = ae.getAvailablePairsBefore(s);
                // logger.debug("availPairs: "+availPairs);
                Iterator availIt = availPairs.iterator();
                while (availIt.hasNext()) {
                    UnitValueBoxPair up = (UnitValueBoxPair) availIt.next();
                    if (up.getValueBox().getValue().equivTo(v)) {
                        // create a local for temp storage.
                        // (we could check to see that the def must-reach, I guess...)
                        String newName = "$cseTmp" + counter;
                        counter++;
                        while (localNames.contains(newName)) {
                            newName = "$cseTmp" + counter;
                            counter++;
                        }
                        Local l = Jimple.v().newLocal(newName, Type.toMachineType(v.getType()));
                        b.getLocals().add(l);
                        // I hope it's always an AssignStmt -- Jimple should guarantee this.
                        AssignStmt origCalc = (AssignStmt) up.getUnit();
                        Value origLHS = origCalc.getLeftOp();
                        origCalc.setLeftOp(l);
                        Unit copier = Jimple.v().newAssignStmt(origLHS, l);
                        units.insertAfter(copier, origCalc);
                        ((AssignStmt) s).setRightOp(l);
                        copier.addTag(new StringTag("Common sub-expression"));
                        s.addTag(new StringTag("Common sub-expression"));
                    // logger.debug("added tag to : "+copier);
                    // logger.debug("added tag to : "+s);
                    }
                }
            }
        }
    }
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     Eliminating common subexpressions done!");
}
Also used : PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester)

Example 3 with PASideEffectTester

use of soot.jimple.toolkits.pointer.PASideEffectTester in project soot by Sable.

the class LazyCodeMotion method internalTransform.

/**
 * performs the lazy code motion.
 */
protected void internalTransform(Body b, String phaseName, Map<String, String> opts) {
    LCMOptions options = new LCMOptions(opts);
    HashMap<EquivalentValue, Local> expToHelper = new HashMap<EquivalentValue, Local>();
    Chain<Unit> unitChain = b.getUnits();
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "] Performing Lazy Code Motion...");
    if (options.unroll())
        new LoopConditionUnroller().transform(b, phaseName + ".lcu");
    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);
        }
    };
    FlowUniverse<EquivalentValue> universe = new CollectionFlowUniverse<EquivalentValue>(unitToEquivRhs.values());
    BoundedFlowSet<EquivalentValue> set = new ArrayPackedSet<EquivalentValue>(universe);
    /* 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;
    DownSafetyAnalysis downSafe;
    EarliestnessComputation earliest;
    DelayabilityAnalysis delay;
    NotIsolatedAnalysis notIsolated;
    LatestComputation latest;
    if (options.safety() == LCMOptions.safety_safe)
        upSafe = new UpSafetyAnalysis(graph, unitToNoExceptionEquivRhs, sideEffect, set);
    else
        upSafe = new UpSafetyAnalysis(graph, unitToEquivRhs, sideEffect, set);
    if (options.safety() == LCMOptions.safety_unsafe)
        downSafe = new DownSafetyAnalysis(graph, unitToEquivRhs, sideEffect, set);
    else {
        downSafe = new DownSafetyAnalysis(graph, unitToNoExceptionEquivRhs, sideEffect, set);
        /* we include the exception-throwing expressions at their uses */
        Iterator<Unit> unitIt = unitChain.iterator();
        while (unitIt.hasNext()) {
            Unit currentUnit = unitIt.next();
            EquivalentValue rhs = unitToEquivRhs.get(currentUnit);
            if (rhs != null)
                downSafe.getFlowBefore(currentUnit).add(rhs);
        }
    }
    earliest = new EarliestnessComputation(graph, upSafe, downSafe, sideEffect, set);
    delay = new DelayabilityAnalysis(graph, earliest, unitToEquivRhs, set);
    latest = new LatestComputation(graph, delay, unitToEquivRhs, set);
    notIsolated = new NotIsolatedAnalysis(graph, latest, unitToEquivRhs, set);
    LocalCreation localCreation = new LocalCreation(b.getLocals(), PREFIX);
    /* debug */
    /*
		 * { logger.debug("========" + b.getMethod().getName()); Iterator
		 * unitIt = unitChain.iterator(); while (unitIt.hasNext()) { Unit
		 * currentUnit = (Unit) unitIt.next(); Value equiVal =
		 * (Value)unitToEquivRhs.get(currentUnit); FlowSet latestSet =
		 * (FlowSet)latest.getFlowBefore(currentUnit); FlowSet notIsolatedSet =
		 * (FlowSet)notIsolated.getFlowAfter(currentUnit); FlowSet delaySet =
		 * (FlowSet)delay.getFlowBefore(currentUnit); FlowSet earlySet =
		 * ((FlowSet)earliest.getFlowBefore(currentUnit)); FlowSet upSet =
		 * (FlowSet)upSafe.getFlowBefore(currentUnit); FlowSet downSet =
		 * (FlowSet)downSafe.getFlowBefore(currentUnit);
		 * logger.debug(""+currentUnit); logger.debug(" rh: " + equiVal);
		 * logger.debug(" up: " + upSet); logger.debug(" do: " +
		 * downSet); logger.debug(" is: " + notIsolatedSet);
		 * logger.debug(" ea: " + earlySet); logger.debug(" db: " +
		 * delaySet); logger.debug(" la: " + latestSet); } }
		 */
    {
        /* insert the computations */
        for (Iterator<Unit> unitIt = unitChain.snapshotIterator(); unitIt.hasNext(); ) {
            Unit currentUnit = unitIt.next();
            FlowSet<EquivalentValue> latestSet = latest.getFlowBefore(currentUnit);
            FlowSet<EquivalentValue> notIsolatedSet = notIsolated.getFlowAfter(currentUnit);
            FlowSet<EquivalentValue> insertHere = latestSet.clone();
            insertHere.intersection(notIsolatedSet, insertHere);
            for (EquivalentValue equiVal : insertHere) {
                /* get the unic helper-name for this expression */
                Local helper = expToHelper.get(equiVal);
                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 */
        Iterator<Unit> unitIt = unitChain.iterator();
        while (unitIt.hasNext()) {
            Unit currentUnit = (Unit) unitIt.next();
            EquivalentValue rhs = (EquivalentValue) unitToEquivRhs.get(currentUnit);
            if (rhs != null) {
                FlowSet<EquivalentValue> latestSet = latest.getFlowBefore(currentUnit);
                FlowSet<EquivalentValue> notIsolatedSet = notIsolated.getFlowAfter(currentUnit);
                if (!latestSet.contains(rhs) && notIsolatedSet.contains(rhs)) {
                    Local helper = expToHelper.get(rhs);
                    try {
                        if (helper != null)
                            ((AssignStmt) currentUnit).setRightOp(helper);
                    } catch (RuntimeException e) {
                        logger.debug("Error on " + b.getMethod().getName());
                        logger.debug("" + currentUnit.toString());
                        logger.debug("" + latestSet);
                        logger.debug("" + notIsolatedSet);
                        throw e;
                    }
                }
            }
        }
    }
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     Lazy Code Motion done.");
}
Also used : PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) LCMOptions(soot.options.LCMOptions)

Aggregations

PASideEffectTester (soot.jimple.toolkits.pointer.PASideEffectTester)3 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 LocalCreation (soot.jimple.toolkits.scalar.LocalCreation)1 BCMOptions (soot.options.BCMOptions)1 LCMOptions (soot.options.LCMOptions)1 BriefUnitGraph (soot.toolkits.graph.BriefUnitGraph)1 UnitGraph (soot.toolkits.graph.UnitGraph)1 UnitMap (soot.util.UnitMap)1