private boolean removeBeginNode() { List heads = getHeads(); if (heads.size() != 1) { // System.out.println("heads: "+heads); // System.out.println("Error: the size of heads is not equal to 1!"); return false; // System.exit(1); } else { JPegStmt head = (JPegStmt) heads.get(0); // System.out.println("test head: "+head); if (!head.getName().equals("begin")) { System.err.println("Error: the head is not begin node!"); System.exit(1); } // remove begin node from heads list heads.remove(0); // set the preds list of the succs of head to a new list and put succs of head into heads Iterator succOfHeadIt = getSuccsOf(head).iterator(); while (succOfHeadIt.hasNext()) { JPegStmt succOfHead = (JPegStmt) succOfHeadIt.next(); unitToPreds.put(succOfHead, new ArrayList()); // put succs of head into heads heads.add(succOfHead); } // remove begin node from inlinee Peg if (!mainPegChain.remove(head)) { System.err.println("fail to remove begin node in from mainPegChain!"); System.exit(1); } if (!allNodes.contains(head)) { System.err.println("fail to find begin node in FlowSet allNodes!"); System.exit(1); } else { allNodes.remove(head); } // remove begin node from unitToSuccs if (unitToSuccs.containsKey(head)) { unitToSuccs.remove(head); } } return true; }
/** * This method pushes all newExpr down to be the stmt directly before every invoke of the init * only if they are in the types list */ public void internalTransform(Body b, String phaseName, Map options) { JimpleBody body = (JimpleBody) b; if (Options.v().verbose()) G.v().out.println("[" + body.getMethod().getName() + "] Folding Jimple constructors..."); Chain units = body.getUnits(); List<Unit> stmtList = new ArrayList<Unit>(); stmtList.addAll(units); Iterator<Unit> it = stmtList.iterator(); Iterator<Unit> nextStmtIt = stmtList.iterator(); // start ahead one nextStmtIt.next(); SmartLocalDefs localDefs = SmartLocalDefsPool.v().getSmartLocalDefsFor(body); UnitGraph graph = localDefs.getGraph(); LocalUses localUses = new SimpleLocalUses(graph, localDefs); /* fold in NewExpr's with specialinvoke's */ while (it.hasNext()) { Stmt s = (Stmt) it.next(); if (!(s instanceof AssignStmt)) continue; /* this should be generalized to ArrayRefs */ // only deal with stmts that are an local = newExpr Value lhs = ((AssignStmt) s).getLeftOp(); if (!(lhs instanceof Local)) continue; Value rhs = ((AssignStmt) s).getRightOp(); if (!(rhs instanceof NewExpr)) continue; // check if very next statement is invoke --> // this indicates there is no control flow between // new and invoke and should do nothing if (nextStmtIt.hasNext()) { Stmt next = (Stmt) nextStmtIt.next(); if (next instanceof InvokeStmt) { InvokeStmt invoke = (InvokeStmt) next; if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) { SpecialInvokeExpr invokeExpr = (SpecialInvokeExpr) invoke.getInvokeExpr(); if (invokeExpr.getBase() == lhs) { break; } } } } // check if new is in the types list - only process these if (!types.contains(((NewExpr) rhs).getType())) continue; List lu = localUses.getUsesOf(s); Iterator luIter = lu.iterator(); boolean MadeNewInvokeExpr = false; while (luIter.hasNext()) { Unit use = ((UnitValueBoxPair) (luIter.next())).unit; if (!(use instanceof InvokeStmt)) continue; InvokeStmt is = (InvokeStmt) use; if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr) || lhs != ((SpecialInvokeExpr) is.getInvokeExpr()).getBase()) continue; // make a new one here AssignStmt constructStmt = Jimple.v() .newAssignStmt(((DefinitionStmt) s).getLeftOp(), ((DefinitionStmt) s).getRightOp()); constructStmt.setRightOp(Jimple.v().newNewExpr(((NewExpr) rhs).getBaseType())); MadeNewInvokeExpr = true; // redirect jumps use.redirectJumpsToThisTo(constructStmt); // insert new one here units.insertBefore(constructStmt, use); constructStmt.addTag(s.getTag("SourceLnPosTag")); } if (MadeNewInvokeExpr) { units.remove(s); } } }
protected void buildSuccsForInlining(JPegStmt stmt, Chain chain, PegGraph inlinee) { // System.out.println("entering buildSuccsForInlining..."); Tag tag = (Tag) stmt.getTags().get(0); // System.out.println("stmt is: "+tag+" "+stmt); /*connect heads of inlinee with the preds of invokeStmt and * delete stmt from the succs list from the preds */ Iterator predIt = getPredsOf(stmt).iterator(); // System.out.println("preds list: "+getPredsOf(stmt)); // System.out.println("preds size: "+getPredsOf(stmt).size()); Iterator headsIt = inlinee.getHeads().iterator(); { // System.out.println("heads: "+inlinee.getHeads()); while (predIt.hasNext()) { JPegStmt pred = (JPegStmt) predIt.next(); // System.out.println("pred: "+pred); List succList = (List) getSuccsOf(pred); // System.out.println("succList of pred: "+succList); int pos = succList.indexOf(stmt); // System.out.println("remove : "+stmt + " from succList: \n"+succList+ "\n of pred" ); // remove invokeStmt succList.remove(pos); while (headsIt.hasNext()) { succList.add(headsIt.next()); } unitToSuccs.put(pred, succList); } { while (headsIt.hasNext()) { Object head = headsIt.next(); List predsOfHeads = new ArrayList(); predsOfHeads.addAll(getPredsOf(head)); unitToPreds.put(head, predsOfHeads); } } /* { predIt = getPredsOf(stmt).iterator(); while (predIt.hasNext()){ JPegStmt s = (JPegStmt)predIt.next(); if (unitToSuccs.containsKey(s)){ Iterator succIt = ((List) unitToSuccs.get(s)).iterator(); while(succIt.hasNext()){ //Object successor = succIt.next(); JPegStmt successor = (JPegStmt)succIt.next(); List predList = (List) unitToPreds.get(successor); if (predList != null) { try { predList.add(s); } catch(NullPointerException e) { System.out.println(s + "successor: " + successor); throw e; } } } } } }*/ } /*connect tails of inlinee with the succ of invokeStmt and * delete stmt from the */ Iterator tailsIt = inlinee.getTails().iterator(); { // System.out.println("tails: "+inlinee.getTails()); while (tailsIt.hasNext()) { Iterator succIt = getSuccsOf(stmt).iterator(); JPegStmt tail = (JPegStmt) tailsIt.next(); List succList = null; if (unitToSuccs.containsKey(tail)) { // System.out.println("error: unitToSucc containsKey: "+tail); succList = (List) getSuccsOf(tail); // System.out.println("succList: "+succList); } else { succList = new ArrayList(); } while (succIt.hasNext()) { JPegStmt succ = (JPegStmt) succIt.next(); succList.add(succ); // System.out.println("succ: "+succ); // remove stmt from the preds list of the succs of itself. List predListOfSucc = getPredsOf(succ); if (predListOfSucc == null) { System.err.println("Error: predListOfSucc is null!"); System.exit(1); } else { if (predListOfSucc.size() != 0) { int pos = predListOfSucc.indexOf(stmt); if (pos > 0 || pos == 0) { // System.out.println("remove stmt: "+stmt+" from the preds list"+predListOfSucc+" // of the succ"); predListOfSucc.remove(pos); } // System.out.println("remove(from PRED): "); } } unitToPreds.put(succ, predListOfSucc); } unitToSuccs.put(tail, succList); // System.out.println("put: "+tail); // System.out.println("succList: "+succList+ "into unitToSucc"); } } // add Nov 1 { tailsIt = inlinee.getTails().iterator(); while (tailsIt.hasNext()) { JPegStmt s = (JPegStmt) tailsIt.next(); if (unitToSuccs.containsKey(s)) { Iterator succIt = unitToSuccs.get(s).iterator(); while (succIt.hasNext()) { // Object successor = succIt.next(); JPegStmt successor = (JPegStmt) succIt.next(); List<JPegStmt> predList = unitToPreds.get(successor); if (predList != null && !predList.contains(s)) { try { predList.add(s); /* Tag tag = (Tag)successor.getTags().get(0); System.out.println("add "+s+" to predlist of "+tag+" "+successor); */ } catch (NullPointerException e) { System.out.println(s + "successor: " + successor); throw e; } } } } } } // end add Nov 1 // System.out.println("stmt: "+stmt); // remove stmt from allNodes and mainPegChain // System.out.println("mainPegChain contains stmt: "+mainPegChain.contains(stmt)); // testPegChain(); if (!allNodes.contains(stmt)) { System.err.println("fail to find begin node in allNodes!"); System.exit(1); } else { allNodes.remove(stmt); // System.out.println("remove from allNode: "+stmt); } if (!chain.contains(stmt)) { System.err.println("Error! Chain does not contains stmt (extending point)!"); System.exit(1); } else { if (!chain.remove(stmt)) { System.err.println("fail to remove invoke stmt in from Chain!"); System.exit(1); } } /* if (!mainPegChain.contains(stmt)){ boolean find = false; //System.out.println("main chain does not contain AFTER"); Set maps = startToThread.entrySet(); for(Iterator iter=maps.iterator(); iter.hasNext();){ Map.Entry entry = (Map.Entry)iter.next(); Object startNode = entry.getKey(); Iterator runIt = ((List)entry.getValue()).iterator(); while (runIt.hasNext()){ Chain chain=(Chain)runIt.next(); if (chain.contains(stmt)) { find = true; if (!chain.remove(stmt)){ System.err.println("fail to remove begin node in from mainPegChain!"); System.exit(1); } break; } } if (find == false){ System.err.println("fail to find stmt: "+stmt+" in chains!"); System.exit(1); } } //this.toString(); } else{ if (!mainPegChain.remove(stmt)) { System.err.println("fail to remove begin node in from mainPegChain!"); System.exit(1); } else{ // System.out.println("remove(from mainchain): "+stmt); } } */ // remove stmt from unitToSuccs and unitToPreds if (unitToSuccs.containsKey(stmt)) { unitToSuccs.remove(stmt); } if (unitToPreds.containsKey(stmt)) { unitToPreds.remove(stmt); } }
private static boolean internalAggregate( StmtBody body, Map<ValueBox, Zone> boxToZone, boolean onlyStackVars) { LocalUses localUses; LocalDefs localDefs; ExceptionalUnitGraph graph; boolean hadAggregation = false; Chain<Unit> units = body.getUnits(); graph = new ExceptionalUnitGraph(body); localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph)); localUses = new SimpleLocalUses(graph, localDefs); List<Unit> unitList = new PseudoTopologicalOrderer<Unit>().newList(graph, false); for (Unit u : unitList) { if (!(u instanceof AssignStmt)) continue; AssignStmt s = (AssignStmt) u; Value lhs = s.getLeftOp(); if (!(lhs instanceof Local)) continue; Local lhsLocal = (Local) lhs; if (onlyStackVars && !lhsLocal.getName().startsWith("$")) continue; List<UnitValueBoxPair> lu = localUses.getUsesOf(s); if (lu.size() != 1) continue; UnitValueBoxPair usepair = lu.get(0); Unit use = usepair.unit; ValueBox useBox = usepair.valueBox; List<Unit> ld = localDefs.getDefsOfAt(lhsLocal, use); if (ld.size() != 1) continue; // Check to make sure aggregation pair in the same zone if (boxToZone.get(s.getRightOpBox()) != boxToZone.get(usepair.valueBox)) { continue; } /* we need to check the path between def and use */ /* to see if there are any intervening re-defs of RHS */ /* in fact, we should check that this path is unique. */ /* if the RHS uses only locals, then we know what to do; if RHS has a method invocation f(a, b, c) or field access, we must ban field writes, other method calls and (as usual) writes to a, b, c. */ boolean cantAggr = false; boolean propagatingInvokeExpr = false; boolean propagatingFieldRef = false; boolean propagatingArrayRef = false; ArrayList<FieldRef> fieldRefList = new ArrayList<FieldRef>(); LinkedList<Value> localsUsed = new LinkedList<Value>(); for (ValueBox vb : s.getUseBoxes()) { Value v = vb.getValue(); if (v instanceof Local) localsUsed.add(v); else if (v instanceof InvokeExpr) propagatingInvokeExpr = true; else if (v instanceof ArrayRef) propagatingArrayRef = true; else if (v instanceof FieldRef) { propagatingFieldRef = true; fieldRefList.add((FieldRef) v); } } // look for a path from s to use in graph. // only look in an extended basic block, though. List<Unit> path = graph.getExtendedBasicBlockPathBetween(s, use); if (path == null) continue; Iterator<Unit> pathIt = path.iterator(); // skip s. if (pathIt.hasNext()) pathIt.next(); while (pathIt.hasNext() && !cantAggr) { Stmt between = (Stmt) (pathIt.next()); if (between != use) { // Check for killing definitions for (ValueBox vb : between.getDefBoxes()) { Value v = vb.getValue(); if (localsUsed.contains(v)) { cantAggr = true; break; } if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) { if (v instanceof FieldRef) { if (propagatingInvokeExpr) { cantAggr = true; break; } else if (propagatingFieldRef) { // Can't aggregate a field access if passing a definition of a field // with the same name, because they might be aliased for (FieldRef fieldRef : fieldRefList) { if (((FieldRef) v).getField() == fieldRef.getField()) { cantAggr = true; break; } } } } else if (v instanceof ArrayRef) { if (propagatingInvokeExpr) { // Cannot aggregate an invoke expr past an array write cantAggr = true; break; } else if (propagatingArrayRef) { // cannot aggregate an array read past a write // this is somewhat conservative // (if types differ they may not be aliased) cantAggr = true; break; } } } } // Make sure not propagating past a {enter,exit}Monitor if (propagatingInvokeExpr && between instanceof MonitorStmt) cantAggr = true; } // Check for intervening side effects due to method calls if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) { for (final ValueBox box : between.getUseBoxes()) { if (between == use && box == useBox) { // Reached use point, stop looking for // side effects break; } Value v = box.getValue(); if (v instanceof InvokeExpr || (propagatingInvokeExpr && (v instanceof FieldRef || v instanceof ArrayRef))) { cantAggr = true; break; } } } } // we give up: can't aggregate. if (cantAggr) { continue; } /* assuming that the d-u chains are correct, */ /* we need not check the actual contents of ld */ Value aggregatee = s.getRightOp(); if (usepair.valueBox.canContainValue(aggregatee)) { boolean wasSimpleCopy = isSimpleCopy(usepair.unit); usepair.valueBox.setValue(aggregatee); units.remove(s); hadAggregation = true; // clean up the tags. If s was not a simple copy, the new statement should get // the tags of s. // OK, this fix was wrong. The condition should not be // "If s was not a simple copy", but rather "If usepair.unit // was a simple copy". This way, when there's a load of a constant // followed by an invoke, the invoke gets the tags. if (wasSimpleCopy) { // usepair.unit.removeAllTags(); usepair.unit.addAllTagsOf(s); } } else { /* if(Options.v().verbose()) { G.v().out.println("[debug] failed aggregation"); G.v().out.println("[debug] tried to put "+aggregatee+ " into "+usepair.stmt + ": in particular, "+usepair.valueBox); G.v().out.println("[debug] aggregatee instanceof Expr: " +(aggregatee instanceof Expr)); }*/ } } return hadAggregation; }