Exemple #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);
     }
   }
 }
Exemple #2
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);
   }
 }
 /**
  * The {@link com.oracle.graal.nodes.AbstractEndNode} at the end of the current code path
  * contributes values to {@link com.oracle.graal.nodes.PhiNode}s. Now is a good time to {@link
  * EquationalReasoner#deverbosify(com.oracle.graal.graph.Node) EquationalReasoner#deverbosify}
  * those values.
  *
  * <p>Precondition: inputs haven't been deverbosified yet.
  */
 private void visitAbstractEndNode(AbstractEndNode endNode) {
   MergeNode merge = endNode.merge();
   for (PhiNode phi : merge.phis()) {
     if (phi instanceof ValuePhiNode && phi.getKind() == Kind.Object) {
       assert phi.verify();
       int index = merge.phiPredecessorIndex(endNode);
       ValueNode original = phi.valueAt(index);
       ValueNode reduced = (ValueNode) reasoner.deverbosify(original);
       if (reduced != original) {
         phi.setValueAt(index, reduced);
         // `original` if unused will be removed in finished()
       }
     }
   }
 }
  private Collection<Edge> handleEdge(
      Edge nextEdge,
      Map<Integer, MergeNode> mergeNodes,
      Set<ARGState> elementsOnPath,
      EdgeVisitor callback) {
    ARGState childElement = nextEdge.getChildState();
    CFAEdge edge = nextEdge.getEdge();
    Stack<FunctionBody> functionStack = nextEdge.getStack();

    // clone stack to have a different representation of the function calls and conditions
    // for every element
    functionStack = cloneStack(functionStack);

    // we do not have a single edge, instead a dynamic multi-edge
    if (edge == null) {
      List<CFAEdge> edges = nextEdge.getParentState().getEdgesToChild(childElement);
      for (CFAEdge inner : edges) {
        callback.visit(childElement, inner, functionStack);
      }
    } else {
      callback.visit(childElement, edge, functionStack);
    }

    // how many parents does the child have?
    // ignore parents not on the error path
    int noOfParents = from(childElement.getParents()).filter(in(elementsOnPath)).size();
    assert noOfParents >= 1;

    // handle merging if necessary
    if (noOfParents > 1) {
      assert !((edge instanceof CFunctionCallEdge) || (childElement.isTarget()));

      // this is the end of a condition, determine whether we should continue or backtrack

      int elemId = childElement.getStateId();
      FunctionBody currentFunction = functionStack.peek();
      currentFunction.write("goto label_" + elemId + ";");

      // get the merge node for that node
      MergeNode mergeNode = mergeNodes.get(elemId);
      // if null create new and put in the map
      if (mergeNode == null) {
        mergeNode = new MergeNode(elemId);
        mergeNodes.put(elemId, mergeNode);
      }

      // this tells us the number of edges (entering that node) processed so far
      int noOfProcessedBranches = mergeNode.addBranch(currentFunction);

      // if all edges are processed
      if (noOfParents == noOfProcessedBranches) {
        // all branches are processed, now decide which nodes to remove from the stack
        List<FunctionBody> incomingStacks = mergeNode.getIncomingStates();

        FunctionBody newFunction = processIncomingStacks(incomingStacks);

        // replace the current function body with the right one
        functionStack.pop();
        functionStack.push(newFunction);

        newFunction.write("label_" + elemId + ": ;");

      } else {
        return Collections.emptySet();
      }
    }

    return getRelevantChildrenOfState(childElement, functionStack, elementsOnPath);
  }