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