comparison graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java @ 9129:d0aab82a6046

removed unused code in lowering of instanceof in the context of an IfNode
author Doug Simon <doug.simon@oracle.com>
date Tue, 16 Apr 2013 12:06:30 +0200
parents 92d2bedb5dfc
children 412f6e6dad73
comparison
equal deleted inserted replaced
9128:703228415b74 9129:d0aab82a6046
89 } 89 }
90 90
91 /** 91 /**
92 * Gets the specific replacer object used to replace the usage of an instanceof node with the 92 * Gets the specific replacer object used to replace the usage of an instanceof node with the
93 * result of an instantiated instanceof snippet. 93 * result of an instantiated instanceof snippet.
94 *
95 * @param nUsages
96 * @param tool
94 */ 97 */
95 protected InstanceOfUsageReplacer createReplacer(FloatingNode instanceOf, LoweringTool tool, int nUsages, Instantiation instantiation, Node usage, final StructuredGraph graph) { 98 protected InstanceOfUsageReplacer createReplacer(FloatingNode instanceOf, LoweringTool tool, int nUsages, Instantiation instantiation, Node usage, final StructuredGraph graph) {
96 InstanceOfUsageReplacer replacer; 99 InstanceOfUsageReplacer replacer;
97 if (usage instanceof IfNode) { 100 if (usage instanceof IfNode) {
98 replacer = new IfUsageReplacer(instantiation, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), instanceOf, (IfNode) usage, nUsages == 1, tool); 101 replacer = new IfUsageReplacer(instantiation, ConstantNode.forInt(1, graph), ConstantNode.forInt(0, graph), instanceOf, (IfNode) usage);
99 } else { 102 } else {
100 assert usage instanceof ConditionalNode : "unexpected usage of " + instanceOf + ": " + usage; 103 assert usage instanceof ConditionalNode : "unexpected usage of " + instanceOf + ": " + usage;
101 ConditionalNode c = (ConditionalNode) usage; 104 ConditionalNode c = (ConditionalNode) usage;
102 replacer = new ConditionalUsageReplacer(instantiation, c.trueValue(), c.falseValue(), instanceOf, c); 105 replacer = new ConditionalUsageReplacer(instantiation, c.trueValue(), c.falseValue(), instanceOf, c);
103 } 106 }
188 * Replaces an {@link IfNode} usage of an {@link InstanceOfNode} or 191 * Replaces an {@link IfNode} usage of an {@link InstanceOfNode} or
189 * {@link InstanceOfDynamicNode}. 192 * {@link InstanceOfDynamicNode}.
190 */ 193 */
191 public static class IfUsageReplacer extends InstanceOfUsageReplacer { 194 public static class IfUsageReplacer extends InstanceOfUsageReplacer {
192 195
193 private final boolean solitaryUsage;
194 private final IfNode usage; 196 private final IfNode usage;
195 private final boolean sameBlock; 197
196 198 public IfUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, IfNode usage) {
197 public IfUsageReplacer(Instantiation instantiation, ValueNode trueValue, ValueNode falseValue, FloatingNode instanceOf, IfNode usage, boolean solitaryUsage, LoweringTool tool) {
198 super(instantiation, instanceOf, trueValue, falseValue); 199 super(instantiation, instanceOf, trueValue, falseValue);
199 this.sameBlock = tool.getBlockFor(usage) == tool.getBlockFor(instanceOf);
200 this.solitaryUsage = solitaryUsage;
201 this.usage = usage; 200 this.usage = usage;
202 } 201 }
203 202
204 @Override 203 @Override
205 public void replaceUsingInstantiation() { 204 public void replaceUsingInstantiation() {
206 usage.replaceFirstInput(instanceOf, instantiation.asCondition(trueValue)); 205 usage.replaceFirstInput(instanceOf, instantiation.asCondition(trueValue));
207 }
208
209 private boolean usageFollowsInstantiation() {
210 return instantiation.result != null && instantiation.result.merge().next() == usage;
211 } 206 }
212 207
213 @Override 208 @Override
214 public void replace(ValueNode oldNode, ValueNode newNode) { 209 public void replace(ValueNode oldNode, ValueNode newNode) {
215 assert newNode instanceof PhiNode; 210 assert newNode instanceof PhiNode;
216 assert oldNode == instanceOf; 211 assert oldNode == instanceOf;
217 if (sameBlock && solitaryUsage && usageFollowsInstantiation()) { 212 newNode.inferStamp();
218 removeIntermediateMaterialization(newNode); 213 instantiation.initialize((PhiNode) newNode, trueValue, falseValue);
219 } else { 214 usage.replaceFirstInput(oldNode, instantiation.asCondition(trueValue));
220 newNode.inferStamp();
221 instantiation.initialize((PhiNode) newNode, trueValue, falseValue);
222 usage.replaceFirstInput(oldNode, instantiation.asCondition(trueValue));
223 }
224 }
225
226 /**
227 * Directly wires the incoming edges of the merge at the end of the snippet to the outgoing
228 * edges of the IfNode that uses the materialized result.
229 */
230 private void removeIntermediateMaterialization(ValueNode newNode) {
231 IfNode ifNode = usage;
232 PhiNode phi = (PhiNode) newNode;
233 MergeNode merge = phi.merge();
234 assert merge.stateAfter() == null;
235
236 List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
237 assert phi.valueCount() == mergePredecessors.size();
238
239 List<EndNode> falseEnds = new ArrayList<>(mergePredecessors.size());
240 List<EndNode> trueEnds = new ArrayList<>(mergePredecessors.size());
241
242 int endIndex = 0;
243 for (EndNode end : mergePredecessors) {
244 ValueNode endValue = phi.valueAt(endIndex++);
245 if (endValue == trueValue) {
246 trueEnds.add(end);
247 } else {
248 assert endValue == falseValue;
249 falseEnds.add(end);
250 }
251 }
252
253 BeginNode trueSuccessor = ifNode.trueSuccessor();
254 BeginNode falseSuccessor = ifNode.falseSuccessor();
255 ifNode.setTrueSuccessor(null);
256 ifNode.setFalseSuccessor(null);
257
258 connectEnds(merge, trueEnds, trueSuccessor);
259 connectEnds(merge, falseEnds, falseSuccessor);
260
261 GraphUtil.killCFG(merge);
262 GraphUtil.killCFG(ifNode);
263
264 assert !merge.isAlive() : merge;
265 assert !phi.isAlive() : phi;
266 }
267
268 private static void connectEnds(MergeNode merge, List<EndNode> ends, BeginNode successor) {
269 if (ends.size() == 0) {
270 // InstanceOf has been lowered to always true or always false - this successor is
271 // therefore unreachable.
272 GraphUtil.killCFG(successor);
273 } else if (ends.size() == 1) {
274 EndNode end = ends.get(0);
275 ((FixedWithNextNode) end.predecessor()).setNext(successor);
276 merge.removeEnd(end);
277 GraphUtil.killCFG(end);
278 } else {
279 assert ends.size() > 1;
280 MergeNode newMerge = merge.graph().add(new MergeNode());
281
282 for (EndNode end : ends) {
283 newMerge.addForwardEnd(end);
284 }
285 newMerge.setNext(successor);
286 }
287 } 215 }
288 } 216 }
289 217
290 /** 218 /**
291 * Replaces a {@link ConditionalNode} usage of an {@link InstanceOfNode} or 219 * Replaces a {@link ConditionalNode} usage of an {@link InstanceOfNode} or