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);
  }
예제 #3
0
  @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;
  }