src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java
author chegar
Thu, 17 Oct 2019 20:54:25 +0100
branchdatagramsocketimpl-branch
changeset 58679 9c3209ff7550
parent 58678 9cf78a70fa4f
parent 58299 6df94ce3ab2f
permissions -rw-r--r--
datagramsocketimpl-branch: merge with default
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     1
/*
52910
583fd71c47d6 8214023: Update Graal
dlong
parents: 52578
diff changeset
     2
 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     4
 *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     7
 * published by the Free Software Foundation.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     8
 *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    13
 * accompanied this code).
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    14
 *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    18
 *
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    21
 * questions.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    22
 */
50858
2d3e99a72541 8205824: Update Graal
never
parents: 50330
diff changeset
    23
2d3e99a72541 8205824: Update Graal
never
parents: 50330
diff changeset
    24
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    25
package org.graalvm.compiler.loop.phases;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    26
46807
8b2c620d7092 8186158: Update Graal
iveresov
parents: 46762
diff changeset
    27
import static org.graalvm.compiler.core.common.GraalOptions.MaximumDesiredSize;
8b2c620d7092 8186158: Update Graal
iveresov
parents: 46762
diff changeset
    28
8b2c620d7092 8186158: Update Graal
iveresov
parents: 46762
diff changeset
    29
import java.util.ArrayList;
8b2c620d7092 8186158: Update Graal
iveresov
parents: 46762
diff changeset
    30
import java.util.Iterator;
8b2c620d7092 8186158: Update Graal
iveresov
parents: 46762
diff changeset
    31
import java.util.List;
8b2c620d7092 8186158: Update Graal
iveresov
parents: 46762
diff changeset
    32
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
    33
import jdk.internal.vm.compiler.collections.EconomicMap;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    34
import org.graalvm.compiler.core.common.RetryableBailoutException;
48861
47f19ff9903c 8194819: Update Graal
iveresov
parents: 47216
diff changeset
    35
import org.graalvm.compiler.core.common.calc.CanonicalCondition;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    36
import org.graalvm.compiler.debug.DebugContext;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    37
import org.graalvm.compiler.graph.Graph.Mark;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    38
import org.graalvm.compiler.graph.Node;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    39
import org.graalvm.compiler.graph.Position;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    40
import org.graalvm.compiler.loop.CountedLoopInfo;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    41
import org.graalvm.compiler.loop.InductionVariable.Direction;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    42
import org.graalvm.compiler.loop.LoopEx;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    43
import org.graalvm.compiler.loop.LoopFragmentInside;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    44
import org.graalvm.compiler.loop.LoopFragmentWhole;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    45
import org.graalvm.compiler.nodeinfo.InputType;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    46
import org.graalvm.compiler.nodes.AbstractBeginNode;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    47
import org.graalvm.compiler.nodes.AbstractEndNode;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    48
import org.graalvm.compiler.nodes.AbstractMergeNode;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    49
import org.graalvm.compiler.nodes.BeginNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    50
import org.graalvm.compiler.nodes.ControlSplitNode;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    51
import org.graalvm.compiler.nodes.EndNode;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    52
import org.graalvm.compiler.nodes.FixedNode;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    53
import org.graalvm.compiler.nodes.FixedWithNextNode;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    54
import org.graalvm.compiler.nodes.IfNode;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    55
import org.graalvm.compiler.nodes.LogicNode;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    56
import org.graalvm.compiler.nodes.LoopBeginNode;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
    57
import org.graalvm.compiler.nodes.NodeView;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    58
import org.graalvm.compiler.nodes.PhiNode;
46762
f7defa99f173 8185829: Update Graal
dlong
parents: 46640
diff changeset
    59
import org.graalvm.compiler.nodes.SafepointNode;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    60
import org.graalvm.compiler.nodes.StructuredGraph;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    61
import org.graalvm.compiler.nodes.ValueNode;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
    62
import org.graalvm.compiler.nodes.calc.AddNode;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    63
import org.graalvm.compiler.nodes.calc.CompareNode;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    64
import org.graalvm.compiler.nodes.calc.ConditionalNode;
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
    65
import org.graalvm.compiler.nodes.extended.OpaqueNode;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    66
import org.graalvm.compiler.nodes.extended.SwitchNode;
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54601
diff changeset
    67
import org.graalvm.compiler.nodes.spi.CoreProviders;
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 55509
diff changeset
    68
import org.graalvm.compiler.nodes.util.IntegerHelper;
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    69
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    70
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    71
public abstract class LoopTransformations {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    72
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    73
    private LoopTransformations() {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    74
        // does not need to be instantiated
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    75
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    76
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    77
    public static void peel(LoopEx loop) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    78
        loop.inside().duplicate().insertBefore(loop);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    79
        loop.loopBegin().setLoopFrequency(Math.max(0.0, loop.loopBegin().loopFrequency() - 1));
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    80
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    81
55509
d58442b8abc1 8225497: Update Graal
jwilhelm
parents: 54601
diff changeset
    82
    public static void fullUnroll(LoopEx loop, CoreProviders context, CanonicalizerPhase canonicalizer) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
    83
        // assert loop.isCounted(); //TODO (gd) strengthen : counted with known trip count
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    84
        LoopBeginNode loopBegin = loop.loopBegin();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    85
        StructuredGraph graph = loopBegin.graph();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    86
        int initialNodeCount = graph.getNodeCount();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    87
        while (!loopBegin.isDeleted()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    88
            Mark mark = graph.getMark();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    89
            peel(loop);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    90
            canonicalizer.applyIncremental(graph, context, mark);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    91
            loop.invalidateFragments();
46344
694c102fd8ed 8177046: Update Graal
iveresov
parents: 43972
diff changeset
    92
            if (graph.getNodeCount() > initialNodeCount + MaximumDesiredSize.getValue(graph.getOptions()) * 2) {
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    93
                throw new RetryableBailoutException("FullUnroll : Graph seems to grow out of proportion");
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    94
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    95
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    96
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    97
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    98
    public static void unswitch(LoopEx loop, List<ControlSplitNode> controlSplitNodeSet) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
    99
        ControlSplitNode firstNode = controlSplitNodeSet.iterator().next();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   100
        LoopFragmentWhole originalLoop = loop.whole();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   101
        StructuredGraph graph = firstNode.graph();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   102
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   103
        loop.loopBegin().incrementUnswitches();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   104
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   105
        // create new control split out of loop
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   106
        ControlSplitNode newControlSplit = (ControlSplitNode) firstNode.copyWithInputs();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   107
        originalLoop.entryPoint().replaceAtPredecessor(newControlSplit);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   108
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   109
        /*
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   110
         * The code below assumes that all of the control split nodes have the same successor
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   111
         * structure, which should have been enforced by findUnswitchable.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   112
         */
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   113
        Iterator<Position> successors = firstNode.successorPositions().iterator();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   114
        assert successors.hasNext();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   115
        // original loop is used as first successor
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   116
        Position firstPosition = successors.next();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   117
        AbstractBeginNode originalLoopBegin = BeginNode.begin(originalLoop.entryPoint());
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   118
        firstPosition.set(newControlSplit, originalLoopBegin);
50330
2cbc42a5764b 8202670: Update Graal
dlong
parents: 48861
diff changeset
   119
        originalLoopBegin.setNodeSourcePosition(firstPosition.get(firstNode).getNodeSourcePosition());
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   120
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   121
        while (successors.hasNext()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   122
            Position position = successors.next();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   123
            // create a new loop duplicate and connect it.
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   124
            LoopFragmentWhole duplicateLoop = originalLoop.duplicate();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   125
            AbstractBeginNode newBegin = BeginNode.begin(duplicateLoop.entryPoint());
50330
2cbc42a5764b 8202670: Update Graal
dlong
parents: 48861
diff changeset
   126
            newBegin.setNodeSourcePosition(position.get(firstNode).getNodeSourcePosition());
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   127
            position.set(newControlSplit, newBegin);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   128
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   129
            // For each cloned ControlSplitNode, simplify the proper path
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   130
            for (ControlSplitNode controlSplitNode : controlSplitNodeSet) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   131
                ControlSplitNode duplicatedControlSplit = duplicateLoop.getDuplicatedNode(controlSplitNode);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   132
                if (duplicatedControlSplit.isAlive()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   133
                    AbstractBeginNode survivingSuccessor = (AbstractBeginNode) position.get(duplicatedControlSplit);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   134
                    survivingSuccessor.replaceAtUsages(InputType.Guard, newBegin);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   135
                    graph.removeSplitPropagate(duplicatedControlSplit, survivingSuccessor);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   136
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   137
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   138
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   139
        // original loop is simplified last to avoid deleting controlSplitNode too early
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   140
        for (ControlSplitNode controlSplitNode : controlSplitNodeSet) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   141
            if (controlSplitNode.isAlive()) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   142
                AbstractBeginNode survivingSuccessor = (AbstractBeginNode) firstPosition.get(controlSplitNode);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   143
                survivingSuccessor.replaceAtUsages(InputType.Guard, originalLoopBegin);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   144
                graph.removeSplitPropagate(controlSplitNode, survivingSuccessor);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   145
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   146
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   147
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   148
        // TODO (gd) probabilities need some amount of fixup.. (probably also in other transforms)
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   149
    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   150
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   151
    public static void partialUnroll(LoopEx loop, EconomicMap<LoopBeginNode, OpaqueNode> opaqueUnrolledStrides) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   152
        assert loop.loopBegin().isMainLoop();
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   153
        loop.loopBegin().graph().getDebug().log("LoopPartialUnroll %s", loop);
46762
f7defa99f173 8185829: Update Graal
dlong
parents: 46640
diff changeset
   154
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   155
        LoopFragmentInside newSegment = loop.inside().duplicate();
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   156
        newSegment.insertWithinAfter(loop, opaqueUnrolledStrides);
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   157
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   158
    }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   159
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   160
    // This function splits candidate loops into pre, main and post loops,
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   161
    // dividing the iteration space to facilitate the majority of iterations
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   162
    // being executed in a main loop, which will have RCE implemented upon it.
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   163
    // The initial loop form is constrained to single entry/exit, but can have
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   164
    // flow. The translation looks like:
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   165
    //
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   166
    //  @formatter:off
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   167
    //
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   168
    //       (Simple Loop entry)                   (Pre Loop Entry)
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   169
    //                |                                  |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   170
    //         (LoopBeginNode)                    (LoopBeginNode)
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   171
    //                |                                  |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   172
    //       (Loop Control Test)<------   ==>  (Loop control Test)<------
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   173
    //         /               \       \         /               \       \
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   174
    //    (Loop Exit)      (Loop Body) |    (Loop Exit)      (Loop Body) |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   175
    //        |                |       |        |                |       |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   176
    // (continue code)     (Loop End)  |  if (M < length)*   (Loop End)  |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   177
    //                         \       /       /      \           \      /
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   178
    //                          ----->        /       |            ----->
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   179
    //                                       /  if ( ... )*
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   180
    //                                      /     /       \
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   181
    //                                     /     /         \
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   182
    //                                    /     /           \
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   183
    //                                   |     /     (Main Loop Entry)
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   184
    //                                   |    |             |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   185
    //                                   |    |      (LoopBeginNode)
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   186
    //                                   |    |             |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   187
    //                                   |    |     (Loop Control Test)<------
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   188
    //                                   |    |      /               \        \
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   189
    //                                   |    |  (Loop Exit)      (Loop Body) |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   190
    //                                    \   \      |                |       |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   191
    //                                     \   \     |            (Loop End)  |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   192
    //                                      \   \    |                \       /
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   193
    //                                       \   \   |                 ------>
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   194
    //                                        \   \  |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   195
    //                                      (Main Loop Merge)*
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   196
    //                                               |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   197
    //                                      (Post Loop Entry)
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   198
    //                                               |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   199
    //                                        (LoopBeginNode)
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   200
    //                                               |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   201
    //                                       (Loop Control Test)<-----
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   202
    //                                        /               \       \
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   203
    //                                    (Loop Exit)     (Loop Body) |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   204
    //                                        |               |       |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   205
    //                                 (continue code)    (Loop End)  |
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   206
    //                                                         \      /
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   207
    //                                                          ----->
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   208
    //
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   209
    // Key: "*" = optional.
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   210
    // @formatter:on
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   211
    //
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   212
    // The value "M" is the maximal value of the loop trip for the original
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   213
    // loop. The value of "length" is applicable to the number of arrays found
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   214
    // in the loop but is reduced if some or all of the arrays are known to be
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   215
    // the same length as "M". The maximum number of tests can be equal to the
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   216
    // number of arrays in the loop, where multiple instances of an array are
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   217
    // subsumed into a single test for that arrays length.
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   218
    //
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   219
    // If the optional main loop entry tests are absent, the Pre Loop exit
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   220
    // connects to the Main loops entry and there is no merge hanging off the
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   221
    // main loops exit to converge flow from said tests. All split use data
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   222
    // flow is mitigated through phi(s) in the main merge if present and
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   223
    // passed through the main and post loop phi(s) from the originating pre
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   224
    // loop with final phi(s) and data flow patched to the "continue code".
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   225
    // The pre loop is constrained to one iteration for now and will likely
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   226
    // be updated to produce vector alignment if applicable.
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   227
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   228
    public static LoopBeginNode insertPrePostLoops(LoopEx loop) {
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   229
        StructuredGraph graph = loop.loopBegin().graph();
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   230
        graph.getDebug().log("LoopTransformations.insertPrePostLoops %s", loop);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   231
        LoopFragmentWhole preLoop = loop.whole();
46762
f7defa99f173 8185829: Update Graal
dlong
parents: 46640
diff changeset
   232
        CountedLoopInfo preCounted = loop.counted();
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   233
        LoopBeginNode preLoopBegin = loop.loopBegin();
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   234
        AbstractBeginNode preLoopExitNode = preCounted.getCountedExit();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   235
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   236
        assert preLoop.nodes().contains(preLoopBegin);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   237
        assert preLoop.nodes().contains(preLoopExitNode);
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   238
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   239
        // Each duplication is inserted after the original, ergo create the post loop first
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   240
        LoopFragmentWhole mainLoop = preLoop.duplicate();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   241
        LoopFragmentWhole postLoop = preLoop.duplicate();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   242
        preLoopBegin.incrementSplits();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   243
        preLoopBegin.incrementSplits();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   244
        preLoopBegin.setPreLoop();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   245
        graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, graph, "After duplication");
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   246
        LoopBeginNode mainLoopBegin = mainLoop.getDuplicatedNode(preLoopBegin);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   247
        mainLoopBegin.setMainLoop();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   248
        LoopBeginNode postLoopBegin = postLoop.getDuplicatedNode(preLoopBegin);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   249
        postLoopBegin.setPostLoop();
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   250
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   251
        AbstractBeginNode postLoopExitNode = postLoop.getDuplicatedNode(preLoopExitNode);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   252
        EndNode postEndNode = getBlockEndAfterLoopExit(postLoopExitNode);
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   253
        AbstractMergeNode postMergeNode = postEndNode.merge();
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   254
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   255
        // Update the main loop phi initialization to carry from the pre loop
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   256
        for (PhiNode prePhiNode : preLoopBegin.phis()) {
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   257
            PhiNode mainPhiNode = mainLoop.getDuplicatedNode(prePhiNode);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   258
            mainPhiNode.setValueAt(0, prePhiNode);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   259
        }
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   260
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   261
        AbstractBeginNode mainLoopExitNode = mainLoop.getDuplicatedNode(preLoopExitNode);
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   262
        EndNode mainEndNode = getBlockEndAfterLoopExit(mainLoopExitNode);
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   263
        AbstractMergeNode mainMergeNode = mainEndNode.merge();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   264
        AbstractEndNode postEntryNode = postLoopBegin.forwardEnd();
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   265
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   266
        // Exits have been merged, find the continuation below the merge
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   267
        FixedNode continuationNode = mainMergeNode.next();
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   268
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   269
        // In the case of no Bounds tests, we just flow right into the main loop
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   270
        AbstractBeginNode mainLandingNode = BeginNode.begin(postEntryNode);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   271
        mainLoopExitNode.setNext(mainLandingNode);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   272
        preLoopExitNode.setNext(mainLoopBegin.forwardEnd());
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   273
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   274
        // Add and update any phi edges as per merge usage as needed and update usages
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   275
        processPreLoopPhis(loop, mainLoop, postLoop);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   276
        continuationNode.predecessor().clearSuccessors();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   277
        postLoopExitNode.setNext(continuationNode);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   278
        cleanupMerge(postMergeNode, postLoopExitNode);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   279
        cleanupMerge(mainMergeNode, mainLandingNode);
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   280
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   281
        // Change the preLoop to execute one iteration for now
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   282
        updatePreLoopLimit(preCounted);
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   283
        preLoopBegin.setLoopFrequency(1);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   284
        mainLoopBegin.setLoopFrequency(Math.max(0.0, mainLoopBegin.loopFrequency() - 2));
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   285
        postLoopBegin.setLoopFrequency(Math.max(0.0, postLoopBegin.loopFrequency() - 1));
46762
f7defa99f173 8185829: Update Graal
dlong
parents: 46640
diff changeset
   286
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   287
        // The pre and post loops don't require safepoints at all
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   288
        for (SafepointNode safepoint : preLoop.nodes().filter(SafepointNode.class)) {
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   289
            graph.removeFixed(safepoint);
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   290
        }
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   291
        for (SafepointNode safepoint : postLoop.nodes().filter(SafepointNode.class)) {
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   292
            graph.removeFixed(safepoint);
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   293
        }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   294
        graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "InsertPrePostLoops %s", loop);
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   295
        return mainLoopBegin;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   296
    }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   297
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   298
    /**
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   299
     * Cleanup the merge and remove the predecessors too.
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   300
     */
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   301
    private static void cleanupMerge(AbstractMergeNode mergeNode, AbstractBeginNode landingNode) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   302
        for (EndNode end : mergeNode.cfgPredecessors().snapshot()) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   303
            mergeNode.removeEnd(end);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   304
            end.safeDelete();
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   305
        }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   306
        mergeNode.prepareDelete(landingNode);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   307
        mergeNode.safeDelete();
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   308
    }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   309
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   310
    private static void processPreLoopPhis(LoopEx preLoop, LoopFragmentWhole mainLoop, LoopFragmentWhole postLoop) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   311
        // process phis for the post loop
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   312
        LoopBeginNode preLoopBegin = preLoop.loopBegin();
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   313
        for (PhiNode prePhiNode : preLoopBegin.phis()) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   314
            PhiNode postPhiNode = postLoop.getDuplicatedNode(prePhiNode);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   315
            PhiNode mainPhiNode = mainLoop.getDuplicatedNode(prePhiNode);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   316
            postPhiNode.setValueAt(0, mainPhiNode);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   317
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   318
            // Build a work list to update the pre loop phis to the post loops phis
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   319
            for (Node usage : prePhiNode.usages().snapshot()) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   320
                if (usage == mainPhiNode) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   321
                    continue;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   322
                }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   323
                if (preLoop.isOutsideLoop(usage)) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   324
                    usage.replaceFirstInput(prePhiNode, postPhiNode);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   325
                }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   326
            }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   327
        }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   328
        for (Node node : preLoop.inside().nodes()) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   329
            for (Node externalUsage : node.usages().snapshot()) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   330
                if (preLoop.isOutsideLoop(externalUsage)) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   331
                    Node postUsage = postLoop.getDuplicatedNode(node);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   332
                    assert postUsage != null;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   333
                    externalUsage.replaceFirstInput(node, postUsage);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   334
                }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   335
            }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   336
        }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   337
    }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   338
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   339
    /**
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   340
     * Find the end of the block following the LoopExit.
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   341
     */
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   342
    private static EndNode getBlockEndAfterLoopExit(AbstractBeginNode exit) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   343
        FixedNode node = exit.next();
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   344
        // Find the last node after the exit blocks starts
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   345
        return getBlockEnd(node);
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   346
    }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   347
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   348
    private static EndNode getBlockEnd(FixedNode node) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   349
        FixedNode curNode = node;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   350
        while (curNode instanceof FixedWithNextNode) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   351
            curNode = ((FixedWithNextNode) curNode).next();
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   352
        }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   353
        return (EndNode) curNode;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   354
    }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   355
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   356
    private static void updatePreLoopLimit(CountedLoopInfo preCounted) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   357
        // Update the pre loops limit test
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   358
        // Make new limit one iteration
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   359
        ValueNode newLimit = AddNode.add(preCounted.getStart(), preCounted.getCounter().strideNode(), NodeView.DEFAULT);
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   360
        // Fetch the variable we are not replacing and configure the one we are
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   361
        ValueNode ub = preCounted.getLimit();
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 55509
diff changeset
   362
        IntegerHelper helper = preCounted.getCounterIntegerHelper();
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   363
        LogicNode entryCheck;
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   364
        if (preCounted.getDirection() == Direction.Up) {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 55509
diff changeset
   365
            entryCheck = helper.createCompareNode(newLimit, ub, NodeView.DEFAULT);
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   366
        } else {
58299
6df94ce3ab2f 8229201: Update Graal
dlong
parents: 55509
diff changeset
   367
            entryCheck = helper.createCompareNode(ub, newLimit, NodeView.DEFAULT);
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   368
        }
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   369
        newLimit = ConditionalNode.create(entryCheck, newLimit, ub, NodeView.DEFAULT);
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   370
        // Re-wire the condition with the new limit
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   371
        CompareNode compareNode = (CompareNode) preCounted.getLimitTest().condition();
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   372
        compareNode.replaceFirstInput(ub, compareNode.graph().addOrUniqueWithInputs(newLimit));
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   373
    }
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   374
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   375
    public static List<ControlSplitNode> findUnswitchable(LoopEx loop) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   376
        List<ControlSplitNode> controls = null;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   377
        ValueNode invariantValue = null;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   378
        for (IfNode ifNode : loop.whole().nodes().filter(IfNode.class)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   379
            if (loop.isOutsideLoop(ifNode.condition())) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   380
                if (controls == null) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   381
                    invariantValue = ifNode.condition();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   382
                    controls = new ArrayList<>();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   383
                    controls.add(ifNode);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   384
                } else if (ifNode.condition() == invariantValue) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   385
                    controls.add(ifNode);
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   386
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   387
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   388
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   389
        if (controls == null) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   390
            SwitchNode firstSwitch = null;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   391
            for (SwitchNode switchNode : loop.whole().nodes().filter(SwitchNode.class)) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   392
                if (switchNode.successors().count() > 1 && loop.isOutsideLoop(switchNode.value())) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   393
                    if (controls == null) {
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   394
                        firstSwitch = switchNode;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   395
                        invariantValue = switchNode.value();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   396
                        controls = new ArrayList<>();
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   397
                        controls.add(switchNode);
54601
c40b2a190173 8221598: Update Graal
jwilhelm
parents: 54084
diff changeset
   398
                    } else if (switchNode.value() == invariantValue) {
c40b2a190173 8221598: Update Graal
jwilhelm
parents: 54084
diff changeset
   399
                        // Fortify: Suppress Null Dereference false positive
c40b2a190173 8221598: Update Graal
jwilhelm
parents: 54084
diff changeset
   400
                        assert firstSwitch != null;
c40b2a190173 8221598: Update Graal
jwilhelm
parents: 54084
diff changeset
   401
c40b2a190173 8221598: Update Graal
jwilhelm
parents: 54084
diff changeset
   402
                        if (firstSwitch.structureEquals(switchNode)) {
c40b2a190173 8221598: Update Graal
jwilhelm
parents: 54084
diff changeset
   403
                            // Only collect switches which test the same values in the same order
c40b2a190173 8221598: Update Graal
jwilhelm
parents: 54084
diff changeset
   404
                            controls.add(switchNode);
c40b2a190173 8221598: Update Graal
jwilhelm
parents: 54084
diff changeset
   405
                        }
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   406
                    }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   407
                }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   408
            }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   409
        }
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   410
        return controls;
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   411
    }
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   412
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   413
    public static boolean isUnrollableLoop(LoopEx loop) {
46807
8b2c620d7092 8186158: Update Graal
iveresov
parents: 46762
diff changeset
   414
        if (!loop.isCounted() || !loop.counted().getCounter().isConstantStride() || !loop.loop().getChildren().isEmpty()) {
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   415
            return false;
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   416
        }
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   417
        assert loop.counted().getDirection() != null;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   418
        LoopBeginNode loopBegin = loop.loopBegin();
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   419
        LogicNode condition = loop.counted().getLimitTest().condition();
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   420
        if (!(condition instanceof CompareNode)) {
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   421
            return false;
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   422
        }
48861
47f19ff9903c 8194819: Update Graal
iveresov
parents: 47216
diff changeset
   423
        if (((CompareNode) condition).condition() == CanonicalCondition.EQ) {
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   424
            condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s condition unsupported %s ", loopBegin, ((CompareNode) condition).condition());
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   425
            return false;
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   426
        }
52578
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   427
        long stride = loop.counted().getCounter().constantStride();
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   428
        try {
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   429
            Math.addExact(stride, stride);
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   430
        } catch (ArithmeticException ae) {
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   431
            condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s doubling the stride overflows %d", loopBegin, stride);
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   432
            return false;
7dd81e82d083 8210777: Update Graal
dlong
parents: 50858
diff changeset
   433
        }
54084
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   434
        if (!loop.canDuplicateLoop()) {
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   435
            return false;
84f10bbf993f 8218074: Update Graal
jwilhelm
parents: 52910
diff changeset
   436
        }
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   437
        if (loopBegin.isMainLoop() || loopBegin.isSimpleLoop()) {
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   438
            // Flow-less loops to partial unroll for now. 3 blocks corresponds to an if that either
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   439
            // exits or continues the loop. There might be fixed and floating work within the loop
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   440
            // as well.
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   441
            if (loop.loop().getBlocks().size() < 3) {
46762
f7defa99f173 8185829: Update Graal
dlong
parents: 46640
diff changeset
   442
                return true;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   443
            }
46963
089674d9949b 8186681: Update Graal
iveresov
parents: 46807
diff changeset
   444
            condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s too large to unroll %s ", loopBegin, loop.loop().getBlocks().size());
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   445
        }
46762
f7defa99f173 8185829: Update Graal
dlong
parents: 46640
diff changeset
   446
        return false;
46640
70bdce04c59b 8183991: Update Graal
iveresov
parents: 46344
diff changeset
   447
    }
43972
1ade39b8381b 8174879: Rename jdk.vm.ci to jdk.internal.vm.ci
kvn
parents:
diff changeset
   448
}