/** * */ package soottocfg.cfg.optimization; import java.util.HashSet; import org.jgrapht.Graphs; import soottocfg.cfg.method.CfgBlock; import soottocfg.cfg.method.CfgEdge; import soottocfg.cfg.method.Method; import soottocfg.cfg.statement.Statement; /** * @author schaef * */ public class FoldStraighLineSeq { /** * */ public FoldStraighLineSeq() { // TODO Auto-generated constructor stub } /** * Searches for two blocks b1 -> b2 s.t. there is * exactly one edge between b1 and b2. Then it folds * b2 into b1, by copying all its statements and outgoing * edges. * @param m */ public void fold(Method m) { boolean fixedpoint = false; while (!fixedpoint) { fixedpoint = true; for (CfgBlock b : new HashSet<CfgBlock>(m.vertexSet())) { if (m.outDegreeOf(b)==1) { CfgBlock suc = Graphs.successorListOf(m, b).get(0); if (foldIfPossible(m, b, suc)) { m.removeVertex(suc); fixedpoint = false; break; } } } } } private boolean foldIfPossible(Method m, CfgBlock b1, CfgBlock b2) { if (m.outDegreeOf(b1)==1 && Graphs.successorListOf(m, b1).contains(b2)) { if (m.inDegreeOf(b2)==1 && Graphs.predecessorListOf(m, b2).contains(b1)) { //there is exactly one edge between b1 and b2 for (Statement s : b2.getStatements()) { b1.addStatement(s.deepCopy()); } for (CfgBlock suc : Graphs.successorListOf(m, b2)) { CfgEdge newEdge = new CfgEdge(); CfgEdge oldEdge = m.getEdge(b2, suc); if (oldEdge.getLabel().isPresent()) { newEdge.setLabel(oldEdge.getLabel().get().deepCopy()); } m.addEdge(b1, suc, newEdge); m.removeEdge(b2, suc); } return true; } } return false; } }