protected boolean addTarget(int pc, CGNode tNode) { allTargets.add(getCallGraph().getNumber(tNode)); Object S = targets.get(pc); if (S == null) { S = tNode; targets.set(pc, S); getCallGraph().addEdge(this, tNode); return true; } else { if (S instanceof CGNode) { if (S.equals(tNode)) { return false; } else { MutableSharedBitVectorIntSet s = new MutableSharedBitVectorIntSet(); s.add(getCallGraph().getNumber((CGNode) S)); s.add(getCallGraph().getNumber(tNode)); getCallGraph().addEdge(this, tNode); targets.set(pc, s); return true; } } else { MutableIntSet s = (MutableIntSet) S; int n = getCallGraph().getNumber(tNode); if (!s.contains(n)) { s.add(n); getCallGraph().addEdge(this, tNode); return true; } else { return false; } } } }
/* * @see com.ibm.wala.ipa.callgraph.impl.BasicCallGraph.NodeImpl#removeTarget(com.ibm.wala.ipa.callgraph.CGNode) */ public void removeTarget(CGNode target) { allTargets.remove(getCallGraph().getNumber(target)); for (IntIterator it = targets.safeIterateIndices(); it.hasNext(); ) { int pc = it.next(); Object value = targets.get(pc); if (value instanceof CGNode) { if (value.equals(target)) { targets.remove(pc); } } else { MutableIntSet s = (MutableIntSet) value; int n = getCallGraph().getNumber(target); if (s.size() > 2) { s.remove(n); } else { assert s.size() == 2; if (s.contains(n)) { s.remove(n); int i = s.intIterator().next(); targets.set(pc, getCallGraph().getNode(i)); } } } } }
@SuppressWarnings("unused") private boolean loopsAreSimple( ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, Set<ISSABasicBlock> scc) throws CancelException { boolean isSimple = true; MutableIntSet sccInts = MutableSparseIntSet.createMutableSparseIntSet(scc.size()); for (ISSABasicBlock bb : scc) { sccInts.add(cfg.getNumber(bb)); } boolean noExit = true; for (ISSABasicBlock bb : scc) { if (cfg.getSuccNodeCount(bb) > 1 && !cfg.getSuccNodeNumbers(bb).isSubset(sccInts)) { noExit = false; // if preds are no subset of the scc block we have a jump to the outside of the scc SSAInstruction last = bb.getLastInstruction(); int[] uses = new int[last.getNumberOfUses()]; for (int i = 0; i < uses.length; i++) { uses[i] = last.getUse(i); } TransitiveDataDependence tdep = new TransitiveDataDependence(scc); tdep.solve(null); for (ISSABasicBlock bb2 : scc) { if (bb2 == bb) { continue; } for (SSAInstruction ii : bb2) { for (int use : uses) { isSimple &= !tdep.influences(ii, use); } // IntSet is = tdep.influences((SSAInstruction) ii); // System.err.println(ii + ": " + is); if (!isSimple) { break; } } if (!isSimple) { break; } } // TODO check if condition is simple... // if (isSimple) { // System.err.println("Simple: " + last + " -> " + // PrettyWalaNames.methodName(bb.getMethod())); // } else { // System.err.println("Not Simple: " + last + " -> " + // PrettyWalaNames.methodName(bb.getMethod())); // } if (!isSimple) { break; } } } return isSimple && !noExit; }