Mercurial > hg > truffle
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 } |