11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.nodes;
24
25 import static org.graalvm.compiler.nodeinfo.InputType.Association;
26 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
27 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
28
29 import java.util.List;
30
31 import org.graalvm.compiler.debug.Debug;
32 import org.graalvm.compiler.graph.IterableNodeType;
33 import org.graalvm.compiler.graph.Node;
34 import org.graalvm.compiler.graph.NodeClass;
35 import org.graalvm.compiler.graph.NodeInputList;
36 import org.graalvm.compiler.graph.iterators.NodeIterable;
37 import org.graalvm.compiler.graph.spi.Simplifiable;
38 import org.graalvm.compiler.graph.spi.SimplifierTool;
39 import org.graalvm.compiler.nodeinfo.NodeInfo;
40 import org.graalvm.compiler.nodes.memory.MemoryPhiNode;
41 import org.graalvm.compiler.nodes.spi.LIRLowerable;
42 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
43 import org.graalvm.compiler.nodes.util.GraphUtil;
44
45 /**
46 * Denotes the merging of multiple control-flow paths.
47 */
48 @NodeInfo(allowedUsageTypes = Association, cycles = CYCLES_0, size = SIZE_0)
49 public abstract class AbstractMergeNode extends BeginStateSplitNode implements IterableNodeType, Simplifiable, LIRLowerable {
50 public static final NodeClass<AbstractMergeNode> TYPE = NodeClass.create(AbstractMergeNode.class);
51
166 AbstractMergeNode merge = origLoopEnd.merge();
167 if (merge instanceof LoopBeginNode && !(origLoopEnd instanceof LoopEndNode)) {
168 return;
169 }
170 // in order to move anchored values to the other merge we would need to check if the
171 // anchors are used by phis of the other merge
172 if (this.anchored().isNotEmpty()) {
173 return;
174 }
175 if (merge.stateAfter() == null && this.stateAfter() != null) {
176 // We hold a state, but the succeeding merge does not => do not combine.
177 return;
178 }
179 for (PhiNode phi : phis()) {
180 for (Node usage : phi.usages()) {
181 if (!(usage instanceof VirtualState) && !merge.isPhiAtMerge(usage)) {
182 return;
183 }
184 }
185 }
186 Debug.log("Split %s into ends for %s.", this, merge);
187 int numEnds = this.forwardEndCount();
188 for (int i = 0; i < numEnds - 1; i++) {
189 AbstractEndNode end = forwardEndAt(numEnds - 1 - i);
190 if (tool != null) {
191 tool.addToWorkList(end);
192 }
193 AbstractEndNode newEnd;
194 if (merge instanceof LoopBeginNode) {
195 newEnd = graph().add(new LoopEndNode((LoopBeginNode) merge));
196 } else {
197 EndNode tmpEnd = graph().add(new EndNode());
198 merge.addForwardEnd(tmpEnd);
199 newEnd = tmpEnd;
200 }
201 for (PhiNode phi : merge.phis()) {
202 ValueNode v = phi.valueAt(origLoopEnd);
203 ValueNode newInput;
204 if (isPhiAtMerge(v)) {
205 PhiNode endPhi = (PhiNode) v;
206 newInput = endPhi.valueAt(end);
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.graalvm.compiler.nodes;
24
25 import static org.graalvm.compiler.nodeinfo.InputType.Association;
26 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
27 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
28
29 import java.util.List;
30
31 import org.graalvm.compiler.graph.IterableNodeType;
32 import org.graalvm.compiler.graph.Node;
33 import org.graalvm.compiler.graph.NodeClass;
34 import org.graalvm.compiler.graph.NodeInputList;
35 import org.graalvm.compiler.graph.iterators.NodeIterable;
36 import org.graalvm.compiler.graph.spi.Simplifiable;
37 import org.graalvm.compiler.graph.spi.SimplifierTool;
38 import org.graalvm.compiler.nodeinfo.NodeInfo;
39 import org.graalvm.compiler.nodes.memory.MemoryPhiNode;
40 import org.graalvm.compiler.nodes.spi.LIRLowerable;
41 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
42 import org.graalvm.compiler.nodes.util.GraphUtil;
43
44 /**
45 * Denotes the merging of multiple control-flow paths.
46 */
47 @NodeInfo(allowedUsageTypes = Association, cycles = CYCLES_0, size = SIZE_0)
48 public abstract class AbstractMergeNode extends BeginStateSplitNode implements IterableNodeType, Simplifiable, LIRLowerable {
49 public static final NodeClass<AbstractMergeNode> TYPE = NodeClass.create(AbstractMergeNode.class);
50
165 AbstractMergeNode merge = origLoopEnd.merge();
166 if (merge instanceof LoopBeginNode && !(origLoopEnd instanceof LoopEndNode)) {
167 return;
168 }
169 // in order to move anchored values to the other merge we would need to check if the
170 // anchors are used by phis of the other merge
171 if (this.anchored().isNotEmpty()) {
172 return;
173 }
174 if (merge.stateAfter() == null && this.stateAfter() != null) {
175 // We hold a state, but the succeeding merge does not => do not combine.
176 return;
177 }
178 for (PhiNode phi : phis()) {
179 for (Node usage : phi.usages()) {
180 if (!(usage instanceof VirtualState) && !merge.isPhiAtMerge(usage)) {
181 return;
182 }
183 }
184 }
185 getDebug().log("Split %s into ends for %s.", this, merge);
186 int numEnds = this.forwardEndCount();
187 for (int i = 0; i < numEnds - 1; i++) {
188 AbstractEndNode end = forwardEndAt(numEnds - 1 - i);
189 if (tool != null) {
190 tool.addToWorkList(end);
191 }
192 AbstractEndNode newEnd;
193 if (merge instanceof LoopBeginNode) {
194 newEnd = graph().add(new LoopEndNode((LoopBeginNode) merge));
195 } else {
196 EndNode tmpEnd = graph().add(new EndNode());
197 merge.addForwardEnd(tmpEnd);
198 newEnd = tmpEnd;
199 }
200 for (PhiNode phi : merge.phis()) {
201 ValueNode v = phi.valueAt(origLoopEnd);
202 ValueNode newInput;
203 if (isPhiAtMerge(v)) {
204 PhiNode endPhi = (PhiNode) v;
205 newInput = endPhi.valueAt(end);
|