Example #1
0
 private static void killEnd(AbstractEndNode end) {
   MergeNode merge = end.merge();
   if (merge != null) {
     merge.removeEnd(end);
     StructuredGraph graph = end.graph();
     if (merge instanceof LoopBeginNode && merge.forwardEndCount() == 0) { // dead loop
       for (PhiNode phi : merge.phis().snapshot()) {
         propagateKill(phi);
       }
       LoopBeginNode begin = (LoopBeginNode) merge;
       // disconnect and delete loop ends & loop exits
       for (LoopEndNode loopend : begin.loopEnds().snapshot()) {
         loopend.predecessor().replaceFirstSuccessor(loopend, null);
         loopend.safeDelete();
       }
       begin.removeExits();
       FixedNode loopBody = begin.next();
       if (loopBody != null) { // for small infinite loops, the body may be killed while
         // killing the loop ends
         killCFG(loopBody);
       }
       begin.safeDelete();
     } else if (merge instanceof LoopBeginNode
         && ((LoopBeginNode) merge).loopEnds().isEmpty()) { // not
       // a
       // loop
       // anymore
       graph.reduceDegenerateLoopBegin((LoopBeginNode) merge);
     } else if (merge.phiPredecessorCount() == 1) { // not a merge anymore
       graph.reduceTrivialMerge(merge);
     }
   }
 }
Example #2
0
 public static void checkRedundantProxy(ProxyNode vpn) {
   AbstractBeginNode proxyPoint = vpn.proxyPoint();
   if (proxyPoint instanceof LoopExitNode) {
     LoopExitNode exit = (LoopExitNode) proxyPoint;
     LoopBeginNode loopBegin = exit.loopBegin();
     ValueNode vpnValue = vpn.value();
     for (ValueNode v : loopBegin.stateAfter().values()) {
       ValueNode v2 = v;
       if (loopBegin.isPhiAtMerge(v2)) {
         v2 = ((PhiNode) v2).valueAt(loopBegin.forwardEnd());
       }
       if (vpnValue == v2) {
         Collection<PhiNode> phiUsages = vpn.usages().filter(PhiNode.class).snapshot();
         Collection<ProxyNode> proxyUsages = vpn.usages().filter(ProxyNode.class).snapshot();
         vpn.graph().replaceFloating(vpn, vpnValue);
         for (PhiNode phi : phiUsages) {
           checkRedundantPhi(phi);
         }
         for (ProxyNode proxy : proxyUsages) {
           checkRedundantProxy(proxy);
         }
         return;
       }
     }
   }
 }
Example #3
0
 private void visitForward(NodeBitMap visited, Node node) {
   if (node != null && !visited.isMarked(node)) {
     visited.mark(node);
     if (node.predecessor() != null) {
       visitForward(visited, node.predecessor());
     }
     if (node instanceof MergeNode) {
       // make sure that the cfg predecessors of a MergeNode are processed first
       MergeNode merge = (MergeNode) node;
       for (int i = 0; i < merge.forwardEndCount(); i++) {
         visitForward(visited, merge.forwardEndAt(i));
       }
     }
     for (Node input : node.inputs()) {
       visitForward(visited, input);
     }
     if (node instanceof LoopBeginNode) {
       LoopBeginNode loopBegin = (LoopBeginNode) node;
       for (LoopEndNode loopEnd : loopBegin.loopEnds()) {
         visitForward(visited, loopEnd);
       }
     }
     nodes.add(node);
   }
 }
Example #4
0
 public void reduceDegenerateLoopBegin(LoopBeginNode begin) {
   assert begin.loopEnds().isEmpty() : "Loop begin still has backedges";
   if (begin.forwardEndCount() == 1) { // bypass merge and remove
     reduceTrivialMerge(begin);
   } else { // convert to merge
     AbstractMergeNode merge = this.add(new MergeNode());
     this.replaceFixedWithFixed(begin, merge);
   }
 }
Example #5
0
 public static void normalizeLoopBegin(LoopBeginNode begin) {
   // Delete unnecessary loop phi functions, i.e., phi functions where all inputs are either
   // the same or the phi itself.
   for (PhiNode phi : begin.phis().snapshot()) {
     GraphUtil.checkRedundantPhi(phi);
   }
   for (LoopExitNode exit : begin.loopExits()) {
     for (ProxyNode vpn : exit.proxies().snapshot()) {
       GraphUtil.checkRedundantProxy(vpn);
     }
   }
 }
Example #6
0
 public void reduceTrivialMerge(AbstractMergeNode merge) {
   assert merge.forwardEndCount() == 1;
   assert !(merge instanceof LoopBeginNode) || ((LoopBeginNode) merge).loopEnds().isEmpty();
   for (PhiNode phi : merge.phis().snapshot()) {
     assert phi.valueCount() == 1;
     ValueNode singleValue = phi.valueAt(0);
     phi.replaceAtUsagesAndDelete(singleValue);
   }
   // remove loop exits
   if (merge instanceof LoopBeginNode) {
     ((LoopBeginNode) merge).removeExits();
   }
   AbstractEndNode singleEnd = merge.forwardEndAt(0);
   FixedNode sux = merge.next();
   FrameState stateAfter = merge.stateAfter();
   // evacuateGuards
   merge.prepareDelete((FixedNode) singleEnd.predecessor());
   merge.safeDelete();
   if (stateAfter != null && stateAfter.isAlive() && stateAfter.hasNoUsages()) {
     GraphUtil.killWithUnusedFloatingInputs(stateAfter);
   }
   if (sux == null) {
     singleEnd.replaceAtPredecessor(null);
     singleEnd.safeDelete();
   } else {
     singleEnd.replaceAndDelete(sux);
   }
 }
Example #7
0
 public void detectedCountedLoops() {
   for (LoopEx loop : loops()) {
     InductionVariables ivs = new InductionVariables(loop);
     LoopBeginNode loopBegin = loop.loopBegin();
     FixedNode next = loopBegin.next();
     while (next instanceof FixedGuardNode || next instanceof ValueAnchorNode) {
       next = ((FixedWithNextNode) next).next();
     }
     if (next instanceof IfNode) {
       IfNode ifNode = (IfNode) next;
       boolean negated = false;
       if (!loopBegin.isLoopExit(ifNode.falseSuccessor())) {
         if (!loopBegin.isLoopExit(ifNode.trueSuccessor())) {
           continue;
         }
         negated = true;
       }
       LogicNode ifTest = ifNode.condition();
       if (!(ifTest instanceof IntegerLessThanNode)) {
         if (ifTest instanceof IntegerBelowThanNode) {
           Debug.log("Ignored potential Counted loop at %s with |<|", loopBegin);
         }
         continue;
       }
       IntegerLessThanNode lessThan = (IntegerLessThanNode) ifTest;
       Condition condition = null;
       InductionVariable iv = null;
       ValueNode limit = null;
       if (loop.isOutsideLoop(lessThan.x())) {
         iv = ivs.get(lessThan.y());
         if (iv != null) {
           condition = lessThan.condition().mirror();
           limit = lessThan.x();
         }
       } else if (loop.isOutsideLoop(lessThan.y())) {
         iv = ivs.get(lessThan.x());
         if (iv != null) {
           condition = lessThan.condition();
           limit = lessThan.y();
         }
       }
       if (condition == null) {
         continue;
       }
       if (negated) {
         condition = condition.negate();
       }
       boolean oneOff = false;
       switch (condition) {
         case LE:
           oneOff = true; // fall through
         case LT:
           if (iv.direction() != Direction.Up) {
             continue;
           }
           break;
         case GE:
           oneOff = true; // fall through
         case GT:
           if (iv.direction() != Direction.Down) {
             continue;
           }
           break;
         default:
           throw GraalInternalError.shouldNotReachHere();
       }
       loop.setCounted(
           new CountedLoopInfo(
               loop,
               iv,
               limit,
               oneOff,
               negated ? ifNode.falseSuccessor() : ifNode.trueSuccessor()));
     }
   }
 }