comparison graal/com.oracle.max.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java @ 5059:ed559a528128

Perform renames on files.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 08 Mar 2012 17:57:30 +0100
parents graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/MergeNode.java@113d66f7454d
children 4ed4295ce15f
comparison
equal deleted inserted replaced
5058:26f8371c229c 5059:ed559a528128
1 /*
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
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 com.oracle.max.graal.nodes;
24
25 import static com.oracle.max.graal.graph.iterators.NodePredicates.*;
26
27 import com.oracle.max.graal.debug.*;
28 import com.oracle.max.graal.graph.*;
29 import com.oracle.max.graal.graph.iterators.*;
30 import com.oracle.max.graal.nodes.spi.*;
31
32 /**
33 * Denotes the merging of multiple control-flow paths.
34 */
35 public class MergeNode extends BeginNode implements Node.IterableNodeType, LIRLowerable {
36
37 @Input(notDataflow = true) private final NodeInputList<EndNode> ends = new NodeInputList<>(this);
38
39 @Override
40 public boolean needsStateAfter() {
41 return false;
42 }
43
44 @Override
45 public void generate(LIRGeneratorTool gen) {
46 gen.visitMerge(this);
47 }
48
49 public int forwardEndIndex(EndNode end) {
50 return ends.indexOf(end);
51 }
52
53 public void addForwardEnd(EndNode end) {
54 ends.add(end);
55 }
56
57 public int forwardEndCount() {
58 return ends.size();
59 }
60
61 public EndNode forwardEndAt(int index) {
62 return ends.get(index);
63 }
64
65 @Override
66 public NodeIterable<EndNode> cfgPredecessors() {
67 return ends;
68 }
69
70 /**
71 * Determines if a given node is a phi whose {@linkplain PhiNode#merge() merge} is this node.
72 *
73 * @param value the instruction to test
74 * @return {@code true} if {@code value} is a phi and its merge is {@code this}
75 */
76 public boolean isPhiAtMerge(Node value) {
77 return value instanceof PhiNode && ((PhiNode) value).merge() == this;
78 }
79
80 /**
81 * Removes the given end from the merge, along with the entries corresponding to this end in the phis connected to the merge.
82 * @param pred the end to remove
83 */
84 public void removeEnd(EndNode pred) {
85 int predIndex = phiPredecessorIndex(pred);
86 assert predIndex != -1;
87 deleteEnd(pred);
88 for (PhiNode phi : phis()) {
89 phi.removeInput(predIndex);
90 }
91 }
92
93 protected void deleteEnd(EndNode end) {
94 ends.remove(end);
95 }
96
97 public void clearEnds() {
98 ends.clear();
99 }
100
101 public NodeIterable<EndNode> forwardEnds() {
102 return ends;
103 }
104
105 public int phiPredecessorCount() {
106 return forwardEndCount();
107 }
108
109 public int phiPredecessorIndex(EndNode pred) {
110 return forwardEndIndex(pred);
111 }
112
113 public EndNode phiPredecessorAt(int index) {
114 return forwardEndAt(index);
115 }
116
117 public NodeIterable<PhiNode> phis() {
118 return this.usages().filter(PhiNode.class);
119 }
120
121 @Override
122 public void simplify(SimplifierTool tool) {
123 FixedNode next = next();
124 if (next instanceof LoopEndNode) {
125 LoopEndNode origLoopEnd = (LoopEndNode) next;
126 LoopBeginNode begin = origLoopEnd.loopBegin();
127 for (PhiNode phi : phis()) {
128 for (Node usage : phi.usages().filter(isNotA(FrameState.class))) {
129 if (!begin.isPhiAtMerge(usage)) {
130 return;
131 }
132 }
133 }
134 Debug.log("Split %s into loop ends for %s", this, begin);
135 int numEnds = this.forwardEndCount();
136 StructuredGraph graph = (StructuredGraph) graph();
137 for (int i = 0; i < numEnds - 1; i++) {
138 EndNode end = forwardEndAt(numEnds - 1 - i);
139 LoopEndNode loopEnd = graph.add(new LoopEndNode(begin));
140 for (PhiNode phi : begin.phis()) {
141 ValueNode v = phi.valueAt(origLoopEnd);
142 ValueNode newInput;
143 if (isPhiAtMerge(v)) {
144 PhiNode endPhi = (PhiNode) v;
145 newInput = endPhi.valueAt(end);
146 } else {
147 newInput = v;
148 }
149 phi.addInput(newInput);
150 }
151 this.removeEnd(end);
152 end.replaceAtPredecessors(loopEnd);
153 end.safeDelete();
154 tool.addToWorkList(loopEnd.predecessor());
155 }
156 graph.reduceTrivialMerge(this);
157 }
158 }
159 }