private void addPhiConstraints( CGNode node, ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, ISSABasicBlock b) { // visit each phi instruction in each successor block for (Iterator<? extends IBasicBlock> sbs = cfg.getSuccNodes(b); sbs.hasNext(); ) { ISSABasicBlock sb = (ISSABasicBlock) sbs.next(); if (sb.isExitBlock()) { // an optimization based on invariant that exit blocks should have no // phis. continue; } int n = 0; // set n to be whichPred(this, sb); for (Iterator<? extends IBasicBlock> back = cfg.getPredNodes(sb); back.hasNext(); n++) { if (back.next() == b) { break; } } assert n < cfg.getPredNodeCount(sb); for (Iterator<SSAPhiInstruction> phis = sb.iteratePhis(); phis.hasNext(); ) { SSAPhiInstruction phi = phis.next(); if (phi == null) { continue; } PointerKey def = heapModel.getPointerKeyForLocal(node, phi.getDef()); if (phi.getUse(n) > 0) { PointerKey use = heapModel.getPointerKeyForLocal(node, phi.getUse(n)); addNode(def); addNode(use); addEdge(def, use); } // } // } } } }
/** Add constraints for a particular basic block. */ protected void addBlockInstructionConstraints( CGNode node, ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg, ISSABasicBlock b, StatementVisitor v) { v.setBasicBlock(b); // visit each instruction in the basic block. for (Iterator<SSAInstruction> it = b.iterator(); it.hasNext(); ) { SSAInstruction s = it.next(); if (s != null) { s.visit(v); } } addPhiConstraints(node, cfg, b); }
@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; }