use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.
the class AugmentedStmtGraph method mirror_PredsSuccs.
private void mirror_PredsSuccs(AugmentedStmt as, UnitGraph ug) {
Stmt s = as.get_Stmt();
LinkedList<AugmentedStmt> preds = new LinkedList<AugmentedStmt>(), succs = new LinkedList<AugmentedStmt>();
// mirror the predecessors
for (Unit u : ug.getPredsOf(s)) {
AugmentedStmt po = get_AugStmt((Stmt) u);
if (preds.contains(po) == false)
preds.add(po);
}
// mirror the successors
for (Unit u : ug.getSuccsOf(s)) {
AugmentedStmt so = get_AugStmt((Stmt) u);
if (succs.contains(so) == false)
succs.add(so);
}
// attach the mirrors properly to the AugmentedStmt
if (ug instanceof BriefUnitGraph) {
as.bpreds = preds;
as.bsuccs = succs;
if (preds.size() == 0)
bheads.add(as);
if (succs.size() == 0)
btails.add(as);
} else if (ug instanceof TrapUnitGraph) {
as.cpreds = preds;
as.csuccs = succs;
if (preds.size() == 0)
cheads.add(as);
if (succs.size() == 0)
ctails.add(as);
} else
throw new RuntimeException("Unknown UnitGraph type: " + ug.getClass());
}
use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.
the class AddSwitches method internalTransform.
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
if (b.getMethod().getSignature().indexOf("<clinit>") >= 0)
return;
int weight = soot.jbco.Main.getWeight(phaseName, b.getMethod().getSignature());
if (weight == 0)
return;
New2InitFlowAnalysis fa = new New2InitFlowAnalysis(new BriefUnitGraph(b));
Vector<Unit> zeroheight = new Vector<Unit>();
PatchingChain<Unit> units = b.getUnits();
Unit first = null;
for (Unit unit : units) {
if (unit instanceof IdentityStmt)
continue;
first = unit;
break;
}
Iterator<Unit> it = units.snapshotIterator();
while (it.hasNext()) {
Unit unit = (Unit) it.next();
if (unit instanceof IdentityStmt || checkTraps(unit, b))
continue;
// very conservative estimate about where new-<init> ranges are
if (fa.getFlowAfter(unit).isEmpty() && fa.getFlowBefore(unit).isEmpty()) {
zeroheight.add(unit);
}
}
if (zeroheight.size() < 3)
return;
int idx = 0;
Unit u = null;
for (int i = 0; i < zeroheight.size(); i++) {
idx = Rand.getInt(zeroheight.size() - 1) + 1;
u = (Unit) zeroheight.get(idx);
if (u.fallsThrough())
break;
u = null;
}
// couldn't find a unit that fell through
if (u == null || Rand.getInt(10) > weight)
return;
zeroheight.remove(idx);
while (zeroheight.size() > (weight > 3 ? weight : 3)) {
zeroheight.remove(Rand.getInt(zeroheight.size()));
}
Collection<Local> locals = b.getLocals();
List<Unit> targs = new ArrayList<Unit>();
targs.addAll(zeroheight);
SootField[] ops = FieldRenamer.getRandomOpaques();
Local b1 = Jimple.v().newLocal("addswitchesbool1", BooleanType.v());
locals.add(b1);
Local b2 = Jimple.v().newLocal("addswitchesbool2", BooleanType.v());
locals.add(b2);
if (ops[0].getType() instanceof PrimType) {
units.insertBefore(Jimple.v().newAssignStmt(b1, Jimple.v().newStaticFieldRef(ops[0].makeRef())), u);
} else {
RefType rt = (RefType) ops[0].getType();
SootMethod m = rt.getSootClass().getMethodByName("booleanValue");
Local B = Jimple.v().newLocal("addswitchesBOOL1", rt);
locals.add(B);
units.insertBefore(Jimple.v().newAssignStmt(B, Jimple.v().newStaticFieldRef(ops[0].makeRef())), u);
units.insertBefore(Jimple.v().newAssignStmt(b1, Jimple.v().newVirtualInvokeExpr(B, m.makeRef(), Collections.<Value>emptyList())), u);
}
if (ops[1].getType() instanceof PrimType) {
units.insertBefore(Jimple.v().newAssignStmt(b2, Jimple.v().newStaticFieldRef(ops[1].makeRef())), u);
} else {
RefType rt = (RefType) ops[1].getType();
SootMethod m = rt.getSootClass().getMethodByName("booleanValue");
Local B = Jimple.v().newLocal("addswitchesBOOL2", rt);
locals.add(B);
units.insertBefore(Jimple.v().newAssignStmt(B, Jimple.v().newStaticFieldRef(ops[1].makeRef())), u);
units.insertBefore(Jimple.v().newAssignStmt(b2, Jimple.v().newVirtualInvokeExpr(B, m.makeRef(), Collections.<Value>emptyList())), u);
}
IfStmt ifstmt = Jimple.v().newIfStmt(Jimple.v().newNeExpr(b1, b2), u);
units.insertBefore(ifstmt, u);
Local l = Jimple.v().newLocal("addswitchlocal", IntType.v());
locals.add(l);
units.insertBeforeNoRedirect(Jimple.v().newAssignStmt(l, IntConstant.v(0)), first);
units.insertAfter(Jimple.v().newTableSwitchStmt(l, 1, zeroheight.size(), targs, u), ifstmt);
switchesadded += zeroheight.size() + 1;
Iterator<Unit> tit = targs.iterator();
while (tit.hasNext()) {
Unit nxt = (Unit) tit.next();
if (Rand.getInt(5) < 4) {
units.insertBefore(Jimple.v().newAssignStmt(l, Jimple.v().newAddExpr(l, IntConstant.v(Rand.getInt(3) + 1))), nxt);
}
}
ifstmt.setTarget(u);
}
use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.
the class MoveLoadsAboveIfs method internalTransform.
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
int weight = soot.jbco.Main.getWeight(phaseName, b.getMethod().getSignature());
if (weight == 0)
return;
BriefUnitGraph bug = new BriefUnitGraph(b);
List<Unit> candidates = new ArrayList<Unit>();
List<Unit> visited = new ArrayList<Unit>();
List<Unit> worklist = new ArrayList<Unit>();
worklist.addAll(bug.getHeads());
while (worklist.size() > 0) {
Unit u = (Unit) worklist.remove(0);
if (visited.contains(u))
continue;
visited.add(u);
List<Unit> succs = bug.getSuccsOf(u);
if (u instanceof TargetArgInst) {
if (checkCandidate(succs, bug))
candidates.add(u);
}
for (int i = 0; i < succs.size(); i++) {
Unit o = succs.get(i);
if (!visited.contains(o))
worklist.add(o);
}
}
int orig = movedloads;
boolean changed = false;
PatchingChain<Unit> units = b.getUnits();
for (int i = 0; i < candidates.size(); i++) {
Unit u = candidates.get(i);
List<Unit> succs = bug.getSuccsOf(u);
BLoadInst clone = (BLoadInst) ((BLoadInst) succs.get(0)).clone();
if (u instanceof IfNonNullInst || u instanceof IfNullInst) {
if (category(clone.getOpType()) == 2 || Rand.getInt(10) > weight)
continue;
units.insertBefore(clone, u);
units.insertBefore(Baf.v().newSwapInst(RefType.v(), clone.getOpType()), u);
// units.insertAfter(clone,p);
// units.insertAfter(Baf.v().newSwapInst(RefType.v(),clone.getOpType()),clone);
} else if (u instanceof OpTypeArgInst) {
Type t = ((OpTypeArgInst) u).getOpType();
if (category(t) == 2 || Rand.getInt(10) > weight)
continue;
units.insertBefore(clone, u);
Type t2 = clone.getOpType();
Unit dup;
if (category(t2) == 2) {
dup = Baf.v().newDup2_x2Inst(t2, null, t, t);
} else {
dup = Baf.v().newDup1_x2Inst(t2, t, t);
}
units.insertBefore(dup, u);
units.insertBefore(Baf.v().newPopInst(t2), u);
/*units.insertAfter(clone,p);
Type t2 = clone.getOpType();
Unit dup;
if (category(t2)==2) {
dup = Baf.v().newDup2_x2Inst(t2,null,t,t);
} else {
dup = Baf.v().newDup1_x2Inst(t2,t,t);
}
units.insertAfter(dup,clone);
units.insertAfter(Baf.v().newPopInst(t2),dup);*/
} else {
if (category(clone.getOpType()) == 2 || Rand.getInt(10) > weight)
continue;
units.insertBefore(clone, u);
units.insertBefore(Baf.v().newSwapInst(IntType.v(), clone.getOpType()), u);
// units.insertAfter(clone,p);
// units.insertAfter(Baf.v().newSwapInst(IntType.v(),clone.getOpType()),clone);
}
movedloads++;
// remove old loads after the jump
for (int j = 0; j < succs.size(); j++) {
Unit suc = (Unit) succs.get(j);
List<Unit> sucPreds = bug.getPredsOf(suc);
if (sucPreds.size() > 1) {
if (suc == ((TargetArgInst) u).getTarget())
((TargetArgInst) u).setTarget((Unit) bug.getSuccsOf(suc).get(0));
else {
units.insertAfter(Baf.v().newGotoInst((Unit) bug.getSuccsOf(suc).get(0)), u);
}
} else {
units.remove(suc);
}
}
if (i < candidates.size() - 1)
bug = new BriefUnitGraph(b);
changed = true;
}
if (changed) {
if (output)
out.println((movedloads - orig) + " loads moved above ifs in " + b.getMethod().getSignature());
if (debug)
StackTypeHeightCalculator.calculateStackHeights(b);
}
}
use of soot.toolkits.graph.BriefUnitGraph 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!");
}
use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.
the class NullTransformer method internalTransform.
protected void internalTransform(Body b, String phaseName, java.util.Map options) {
NullnessAnalysis na = new NullnessAnalysis(new BriefUnitGraph(b));
java.util.Iterator uIt = b.getUnits().iterator();
while (uIt.hasNext()) {
Unit u = (Unit) uIt.next();
StringBuffer n = new StringBuffer();
u.addTag(new StringTag("IN: " + na.getFlowBefore(u).toString()));
if (u.fallsThrough()) {
ArraySparseSet s = (ArraySparseSet) na.getFallFlowAfter(u);
u.addTag(new StringTag("FALL: " + s.toString()));
}
if (u.branches()) {
ArraySparseSet t = (ArraySparseSet) na.getBranchFlowAfter(u).get(0);
u.addTag(new StringTag("BRANCH: " + t.toString()));
}
}
}
Aggregations