< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphDecoder.java

Print this page




 449             }
 450         }
 451     }
 452 
 453     protected LoopScope processNextNode(MethodScope methodScope, LoopScope loopScope) {
 454         int nodeOrderId = loopScope.nodesToProcess.nextSetBit(0);
 455         loopScope.nodesToProcess.clear(nodeOrderId);
 456 
 457         FixedNode node = (FixedNode) lookupNode(loopScope, nodeOrderId);
 458         if (node.isDeleted()) {
 459             return loopScope;
 460         }
 461 
 462         if ((node instanceof MergeNode ||
 463                         (node instanceof LoopBeginNode && (methodScope.loopExplosion == LoopExplosionKind.FULL_UNROLL || methodScope.loopExplosion == LoopExplosionKind.FULL_EXPLODE ||
 464                                         methodScope.loopExplosion == LoopExplosionKind.FULL_EXPLODE_UNTIL_RETURN))) &&
 465                         ((AbstractMergeNode) node).forwardEndCount() == 1) {
 466             AbstractMergeNode merge = (AbstractMergeNode) node;
 467             EndNode singleEnd = merge.forwardEndAt(0);
 468 
 469             /*
 470              * In some corner cases, the MergeNode already has PhiNodes. Since there is a single
 471              * EndNode, each PhiNode can only have one input, and we can replace the PhiNode with
 472              * this single input.
 473              */
 474             for (PhiNode phi : merge.phis()) {
 475                 assert phi.inputs().count() == 1 : "input count must match end count";
 476                 Node singlePhiInput = phi.inputs().first();
 477 
 478                 /*
 479                  * We do not have the orderID of the PhiNode anymore, so we need to search through
 480                  * the complete list of nodes to find a match.
 481                  */
 482                 for (int i = 0; i < loopScope.createdNodes.length; i++) {
 483                     if (loopScope.createdNodes[i] == phi) {
 484                         loopScope.createdNodes[i] = singlePhiInput;
 485                     }
 486                 }
 487 
 488                 phi.replaceAndDelete(singlePhiInput);
 489             }
 490 
 491             /* Nodes that would use this merge as the guard need to use the previous block. */
 492             registerNode(loopScope, nodeOrderId, AbstractBeginNode.prevBegin(singleEnd), true, false);
 493 
 494             FixedNode next = makeStubNode(methodScope, loopScope, nodeOrderId + GraphEncoder.BEGIN_NEXT_ORDER_ID_OFFSET);
 495             singleEnd.replaceAtPredecessor(next);
 496 
 497             merge.safeDelete();
 498             singleEnd.safeDelete();
 499             return loopScope;
 500         }
 501 
 502         LoopScope successorAddScope = loopScope;
 503         boolean updatePredecessors = true;
 504         if (node instanceof LoopExitNode) {
 505             if (methodScope.loopExplosion == LoopExplosionKind.FULL_EXPLODE_UNTIL_RETURN || (methodScope.loopExplosion == LoopExplosionKind.MERGE_EXPLODE && loopScope.loopDepth > 1)) {
 506                 /*
 507                  * We do not want to merge loop exits of inner loops. Instead, we want to keep
 508                  * exploding the outer loop separately for every loop exit and then merge the outer
 509                  * loop. Therefore, we create a new LoopScope of the outer loop for every loop exit
 510                  * of the inner loop.


 956             }
 957             merge.addForwardEnd((EndNode) end);
 958         }
 959 
 960         /*
 961          * We create most phi functions lazily. Canonicalization and simplification during decoding
 962          * can lead to dead branches that are not decoded, so we might not need all phi functions
 963          * that the original graph contained. Since we process all predecessors before actually
 964          * processing the merge node, we have the final phi function when processing the merge node.
 965          * The only exception are loop headers of non-exploded loops: since backward branches are
 966          * not processed yet when processing the loop body, we need to create all phi functions
 967          * upfront.
 968          */
 969         boolean lazyPhi = allowLazyPhis() && (!(merge instanceof LoopBeginNode) || methodScope.loopExplosion != LoopExplosionKind.NONE);
 970         int numPhis = methodScope.reader.getUVInt();
 971         for (int i = 0; i < numPhis; i++) {
 972             int phiInputOrderId = readOrderId(methodScope);
 973             int phiNodeOrderId = readOrderId(methodScope);
 974 
 975             ValueNode phiInput = (ValueNode) ensureNodeCreated(methodScope, phiInputScope, phiInputOrderId);
 976 
 977             ValueNode existing = (ValueNode) lookupNode(phiNodeScope, phiNodeOrderId);















 978             if (lazyPhi && (existing == null || existing == phiInput)) {
 979                 /* Phi function not yet necessary. */
 980                 registerNode(phiNodeScope, phiNodeOrderId, phiInput, true, false);
 981 
 982             } else if (!merge.isPhiAtMerge(existing)) {
 983                 /*
 984                  * Phi function is necessary. Create it and fill it with existing inputs as well as
 985                  * the new input.
 986                  */
 987                 registerNode(phiNodeScope, phiNodeOrderId, null, true, true);
 988                 PhiNode phi = (PhiNode) ensureNodeCreated(methodScope, phiNodeScope, phiNodeOrderId);
 989 
 990                 phi.setMerge(merge);
 991                 for (int j = 0; j < merge.phiPredecessorCount() - 1; j++) {
 992                     phi.addInput(existing);
 993                 }
 994                 phi.addInput(phiInput);
 995 
 996             } else {
 997                 /* Phi node has been created before, so just add the new input. */




 449             }
 450         }
 451     }
 452 
 453     protected LoopScope processNextNode(MethodScope methodScope, LoopScope loopScope) {
 454         int nodeOrderId = loopScope.nodesToProcess.nextSetBit(0);
 455         loopScope.nodesToProcess.clear(nodeOrderId);
 456 
 457         FixedNode node = (FixedNode) lookupNode(loopScope, nodeOrderId);
 458         if (node.isDeleted()) {
 459             return loopScope;
 460         }
 461 
 462         if ((node instanceof MergeNode ||
 463                         (node instanceof LoopBeginNode && (methodScope.loopExplosion == LoopExplosionKind.FULL_UNROLL || methodScope.loopExplosion == LoopExplosionKind.FULL_EXPLODE ||
 464                                         methodScope.loopExplosion == LoopExplosionKind.FULL_EXPLODE_UNTIL_RETURN))) &&
 465                         ((AbstractMergeNode) node).forwardEndCount() == 1) {
 466             AbstractMergeNode merge = (AbstractMergeNode) node;
 467             EndNode singleEnd = merge.forwardEndAt(0);
 468 






















 469             /* Nodes that would use this merge as the guard need to use the previous block. */
 470             registerNode(loopScope, nodeOrderId, AbstractBeginNode.prevBegin(singleEnd), true, false);
 471 
 472             FixedNode next = makeStubNode(methodScope, loopScope, nodeOrderId + GraphEncoder.BEGIN_NEXT_ORDER_ID_OFFSET);
 473             singleEnd.replaceAtPredecessor(next);
 474 
 475             merge.safeDelete();
 476             singleEnd.safeDelete();
 477             return loopScope;
 478         }
 479 
 480         LoopScope successorAddScope = loopScope;
 481         boolean updatePredecessors = true;
 482         if (node instanceof LoopExitNode) {
 483             if (methodScope.loopExplosion == LoopExplosionKind.FULL_EXPLODE_UNTIL_RETURN || (methodScope.loopExplosion == LoopExplosionKind.MERGE_EXPLODE && loopScope.loopDepth > 1)) {
 484                 /*
 485                  * We do not want to merge loop exits of inner loops. Instead, we want to keep
 486                  * exploding the outer loop separately for every loop exit and then merge the outer
 487                  * loop. Therefore, we create a new LoopScope of the outer loop for every loop exit
 488                  * of the inner loop.


 934             }
 935             merge.addForwardEnd((EndNode) end);
 936         }
 937 
 938         /*
 939          * We create most phi functions lazily. Canonicalization and simplification during decoding
 940          * can lead to dead branches that are not decoded, so we might not need all phi functions
 941          * that the original graph contained. Since we process all predecessors before actually
 942          * processing the merge node, we have the final phi function when processing the merge node.
 943          * The only exception are loop headers of non-exploded loops: since backward branches are
 944          * not processed yet when processing the loop body, we need to create all phi functions
 945          * upfront.
 946          */
 947         boolean lazyPhi = allowLazyPhis() && (!(merge instanceof LoopBeginNode) || methodScope.loopExplosion != LoopExplosionKind.NONE);
 948         int numPhis = methodScope.reader.getUVInt();
 949         for (int i = 0; i < numPhis; i++) {
 950             int phiInputOrderId = readOrderId(methodScope);
 951             int phiNodeOrderId = readOrderId(methodScope);
 952 
 953             ValueNode phiInput = (ValueNode) ensureNodeCreated(methodScope, phiInputScope, phiInputOrderId);

 954             ValueNode existing = (ValueNode) lookupNode(phiNodeScope, phiNodeOrderId);
 955 
 956             if (existing != null && merge.phiPredecessorCount() == 1) {
 957                 /*
 958                  * When exploding loops and the code after the loop (FULL_EXPLODE_UNTIL_RETURN),
 959                  * then an existing value can already be registered: Parsing of the code before the
 960                  * loop registers it when preparing for the later merge. The code after the loop,
 961                  * which starts with a clone of the values that were created before the loop, sees
 962                  * the stale value when processing the merge the first time. We can safely ignore
 963                  * the stale value because it will never be needed to be merged (we are exploding
 964                  * until we hit a return).
 965                  */
 966                 assert methodScope.loopExplosion == LoopExplosionKind.FULL_EXPLODE_UNTIL_RETURN && phiNodeScope.loopIteration > 0;
 967                 existing = null;
 968             }
 969 
 970             if (lazyPhi && (existing == null || existing == phiInput)) {
 971                 /* Phi function not yet necessary. */
 972                 registerNode(phiNodeScope, phiNodeOrderId, phiInput, true, false);
 973 
 974             } else if (!merge.isPhiAtMerge(existing)) {
 975                 /*
 976                  * Phi function is necessary. Create it and fill it with existing inputs as well as
 977                  * the new input.
 978                  */
 979                 registerNode(phiNodeScope, phiNodeOrderId, null, true, true);
 980                 PhiNode phi = (PhiNode) ensureNodeCreated(methodScope, phiNodeScope, phiNodeOrderId);
 981 
 982                 phi.setMerge(merge);
 983                 for (int j = 0; j < merge.phiPredecessorCount() - 1; j++) {
 984                     phi.addInput(existing);
 985                 }
 986                 phi.addInput(phiInput);
 987 
 988             } else {
 989                 /* Phi node has been created before, so just add the new input. */


< prev index next >