src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/DeoptimizationGroupingPhase.java
changeset 54601 c40b2a190173
parent 52910 583fd71c47d6
child 58299 6df94ce3ab2f
equal deleted inserted replaced
54600:69cfd80f8706 54601:c40b2a190173
    22  */
    22  */
    23 
    23 
    24 
    24 
    25 package org.graalvm.compiler.phases.common;
    25 package org.graalvm.compiler.phases.common;
    26 
    26 
       
    27 import java.util.Iterator;
    27 import java.util.LinkedList;
    28 import java.util.LinkedList;
    28 import java.util.List;
    29 import java.util.List;
    29 
    30 
    30 import org.graalvm.compiler.core.common.cfg.Loop;
    31 import org.graalvm.compiler.core.common.cfg.Loop;
    31 import org.graalvm.compiler.core.common.type.StampFactory;
    32 import org.graalvm.compiler.core.common.type.StampFactory;
    32 import org.graalvm.compiler.debug.DebugCloseable;
    33 import org.graalvm.compiler.debug.DebugCloseable;
    33 import org.graalvm.compiler.nodes.AbstractDeoptimizeNode;
    34 import org.graalvm.compiler.nodes.AbstractDeoptimizeNode;
    34 import org.graalvm.compiler.nodes.AbstractMergeNode;
    35 import org.graalvm.compiler.nodes.AbstractMergeNode;
    35 import org.graalvm.compiler.nodes.DynamicDeoptimizeNode;
    36 import org.graalvm.compiler.nodes.DynamicDeoptimizeNode;
    36 import org.graalvm.compiler.nodes.EndNode;
    37 import org.graalvm.compiler.nodes.EndNode;
    37 import org.graalvm.compiler.nodes.FixedNode;
       
    38 import org.graalvm.compiler.nodes.FrameState;
    38 import org.graalvm.compiler.nodes.FrameState;
    39 import org.graalvm.compiler.nodes.LoopBeginNode;
    39 import org.graalvm.compiler.nodes.LoopBeginNode;
    40 import org.graalvm.compiler.nodes.LoopExitNode;
    40 import org.graalvm.compiler.nodes.LoopExitNode;
    41 import org.graalvm.compiler.nodes.MergeNode;
    41 import org.graalvm.compiler.nodes.MergeNode;
    42 import org.graalvm.compiler.nodes.PhiNode;
    42 import org.graalvm.compiler.nodes.PhiNode;
    57     @Override
    57     @Override
    58     @SuppressWarnings("try")
    58     @SuppressWarnings("try")
    59     protected void run(StructuredGraph graph, MidTierContext context) {
    59     protected void run(StructuredGraph graph, MidTierContext context) {
    60         ControlFlowGraph cfg = null;
    60         ControlFlowGraph cfg = null;
    61         for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
    61         for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
    62             FixedNode target = null;
    62             Iterator<AbstractDeoptimizeNode> iterator = fs.usages().filter(AbstractDeoptimizeNode.class).iterator();
    63             PhiNode reasonActionPhi = null;
    63             if (!iterator.hasNext()) {
    64             PhiNode speculationPhi = null;
    64                 // No deopt
    65             List<AbstractDeoptimizeNode> obsoletes = null;
    65                 continue;
    66             for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) {
    66             }
    67                 if (target == null) {
    67             AbstractDeoptimizeNode first = iterator.next();
    68                     target = deopt;
    68             if (!iterator.hasNext()) {
    69                 } else {
    69                 // Only 1 deopt
    70                     if (cfg == null) {
    70                 continue;
    71                         cfg = ControlFlowGraph.compute(graph, true, true, false, false);
    71             }
    72                     }
    72             // There is more than one deopt, create a merge
    73                     AbstractMergeNode merge;
    73             if (cfg == null) {
    74                     if (target instanceof AbstractDeoptimizeNode) {
    74                 cfg = ControlFlowGraph.compute(graph, true, true, false, false);
    75                         merge = graph.add(new MergeNode());
    75             }
    76                         EndNode firstEnd = graph.add(new EndNode());
    76             AbstractMergeNode merge = graph.add(new MergeNode());
    77                         ValueNode actionAndReason = ((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess());
    77             EndNode firstEnd = graph.add(new EndNode());
    78                         ValueNode speculation = ((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess());
    78             ValueNode actionAndReason = first.getActionAndReason(context.getMetaAccess());
    79                         reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge));
    79             ValueNode speculation = first.getSpeculation(context.getMetaAccess());
    80                         speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge));
    80             PhiNode reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge));
    81                         merge.addForwardEnd(firstEnd);
    81             PhiNode speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge));
    82                         reasonActionPhi.addInput(actionAndReason);
    82             merge.addForwardEnd(firstEnd);
    83                         speculationPhi.addInput(speculation);
    83             reasonActionPhi.addInput(actionAndReason);
    84                         target.replaceAtPredecessor(firstEnd);
    84             speculationPhi.addInput(speculation);
       
    85             first.replaceAtPredecessor(firstEnd);
       
    86             exitLoops(first, firstEnd, cfg);
       
    87             DynamicDeoptimizeNode dynamicDeopt;
       
    88             try (DebugCloseable position = first.withNodeSourcePosition()) {
       
    89                 dynamicDeopt = new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi);
       
    90                 merge.setNext(graph.add(dynamicDeopt));
       
    91             }
       
    92             List<AbstractDeoptimizeNode> obsoletes = new LinkedList<>();
       
    93             obsoletes.add(first);
    85 
    94 
    86                         exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg);
    95             do {
    87                         try (DebugCloseable position = target.withNodeSourcePosition()) {
    96                 AbstractDeoptimizeNode deopt = iterator.next();
    88                             merge.setNext(graph.add(new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi)));
    97                 EndNode newEnd = graph.add(new EndNode());
    89                         }
    98                 merge.addForwardEnd(newEnd);
    90                         obsoletes = new LinkedList<>();
    99                 reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess()));
    91                         obsoletes.add((AbstractDeoptimizeNode) target);
   100                 speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess()));
    92                         target = merge;
   101                 deopt.replaceAtPredecessor(newEnd);
    93                     } else {
   102                 exitLoops(deopt, newEnd, cfg);
    94                         merge = (AbstractMergeNode) target;
   103                 obsoletes.add(deopt);
    95                     }
   104             } while (iterator.hasNext());
    96                     EndNode newEnd = graph.add(new EndNode());
   105 
    97                     merge.addForwardEnd(newEnd);
   106             dynamicDeopt.setStateBefore(fs);
    98                     reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess()));
   107             for (AbstractDeoptimizeNode obsolete : obsoletes) {
    99                     speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess()));
   108                 obsolete.safeDelete();
   100                     deopt.replaceAtPredecessor(newEnd);
       
   101                     exitLoops(deopt, newEnd, cfg);
       
   102                     obsoletes.add(deopt);
       
   103                 }
       
   104             }
       
   105             if (obsoletes != null) {
       
   106                 ((DynamicDeoptimizeNode) ((AbstractMergeNode) target).next()).setStateBefore(fs);
       
   107                 for (AbstractDeoptimizeNode obsolete : obsoletes) {
       
   108                     obsolete.safeDelete();
       
   109                 }
       
   110             }
   109             }
   111         }
   110         }
   112     }
   111     }
   113 
   112 
   114     private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) {
   113     private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) {