28 |
28 |
29 import java.util.List; |
29 import java.util.List; |
30 |
30 |
31 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; |
31 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider; |
32 import org.graalvm.compiler.core.common.type.Stamp; |
32 import org.graalvm.compiler.core.common.type.Stamp; |
|
33 import org.graalvm.compiler.debug.DebugCloseable; |
33 import org.graalvm.compiler.graph.Node; |
34 import org.graalvm.compiler.graph.Node; |
34 import org.graalvm.compiler.graph.NodeClass; |
35 import org.graalvm.compiler.graph.NodeClass; |
35 import org.graalvm.compiler.graph.spi.Canonicalizable; |
36 import org.graalvm.compiler.graph.spi.Canonicalizable; |
36 import org.graalvm.compiler.graph.spi.CanonicalizerTool; |
37 import org.graalvm.compiler.graph.spi.CanonicalizerTool; |
37 import org.graalvm.compiler.nodeinfo.NodeInfo; |
38 import org.graalvm.compiler.nodeinfo.NodeInfo; |
271 * (which is floating and has no inputs). |
272 * (which is floating and has no inputs). |
272 */ |
273 */ |
273 return new CanonicalizeToNullNode(node.stamp); |
274 return new CanonicalizeToNullNode(node.stamp); |
274 } |
275 } |
275 |
276 |
|
277 @SuppressWarnings("try") |
276 private void handleCanonicalization(LoopScope loopScope, int nodeOrderId, FixedNode node, Node c) { |
278 private void handleCanonicalization(LoopScope loopScope, int nodeOrderId, FixedNode node, Node c) { |
277 assert c != node : "unnecessary call"; |
279 assert c != node : "unnecessary call"; |
278 Node canonical = c == null ? canonicalizeFixedNodeToNull(node) : c; |
280 try (DebugCloseable position = graph.withNodeSourcePosition(node)) { |
279 if (!canonical.isAlive()) { |
281 Node canonical = c == null ? canonicalizeFixedNodeToNull(node) : c; |
280 assert !canonical.isDeleted(); |
282 if (!canonical.isAlive()) { |
281 canonical = graph.addOrUniqueWithInputs(canonical); |
283 assert !canonical.isDeleted(); |
282 if (canonical instanceof FixedWithNextNode) { |
284 canonical = graph.addOrUniqueWithInputs(canonical); |
283 graph.addBeforeFixed(node, (FixedWithNextNode) canonical); |
285 if (canonical instanceof FixedWithNextNode) { |
284 } else if (canonical instanceof ControlSinkNode) { |
286 graph.addBeforeFixed(node, (FixedWithNextNode) canonical); |
285 FixedWithNextNode predecessor = (FixedWithNextNode) node.predecessor(); |
287 } else if (canonical instanceof ControlSinkNode) { |
286 predecessor.setNext((ControlSinkNode) canonical); |
288 FixedWithNextNode predecessor = (FixedWithNextNode) node.predecessor(); |
287 List<Node> successorSnapshot = node.successors().snapshot(); |
289 predecessor.setNext((ControlSinkNode) canonical); |
288 node.safeDelete(); |
290 List<Node> successorSnapshot = node.successors().snapshot(); |
289 for (Node successor : successorSnapshot) { |
291 node.safeDelete(); |
290 successor.safeDelete(); |
292 for (Node successor : successorSnapshot) { |
291 } |
293 successor.safeDelete(); |
292 |
294 } |
293 } else { |
295 } else { |
294 assert !(canonical instanceof FixedNode); |
296 assert !(canonical instanceof FixedNode); |
295 } |
297 } |
296 } |
298 } |
297 if (!node.isDeleted()) { |
299 if (!node.isDeleted()) { |
298 GraphUtil.unlinkFixedNode((FixedWithNextNode) node); |
300 GraphUtil.unlinkFixedNode((FixedWithNextNode) node); |
299 node.replaceAtUsagesAndDelete(canonical); |
301 node.replaceAtUsagesAndDelete(canonical); |
300 } |
302 } |
301 assert lookupNode(loopScope, nodeOrderId) == node; |
303 assert lookupNode(loopScope, nodeOrderId) == node; |
302 registerNode(loopScope, nodeOrderId, canonical, true, false); |
304 registerNode(loopScope, nodeOrderId, canonical, true, false); |
303 } |
305 } |
304 |
306 } |
305 @Override |
307 |
|
308 @Override |
|
309 @SuppressWarnings("try") |
306 protected Node handleFloatingNodeBeforeAdd(MethodScope methodScope, LoopScope loopScope, Node node) { |
310 protected Node handleFloatingNodeBeforeAdd(MethodScope methodScope, LoopScope loopScope, Node node) { |
307 if (node instanceof ValueNode) { |
311 if (node instanceof ValueNode) { |
308 ((ValueNode) node).inferStamp(); |
312 ((ValueNode) node).inferStamp(); |
309 } |
313 } |
310 if (node instanceof Canonicalizable) { |
314 if (node instanceof Canonicalizable) { |
311 Node canonical = ((Canonicalizable) node).canonical(canonicalizerTool); |
315 try (DebugCloseable context = graph.withNodeSourcePosition(node)) { |
312 if (canonical == null) { |
316 Node canonical = ((Canonicalizable) node).canonical(canonicalizerTool); |
313 /* |
317 if (canonical == null) { |
314 * This is a possible return value of canonicalization. However, we might need to |
318 /* |
315 * add additional usages later on for which we need a node. Therefore, we just do |
319 * This is a possible return value of canonicalization. However, we might need |
316 * nothing and leave the node in place. |
320 * to add additional usages later on for which we need a node. Therefore, we |
317 */ |
321 * just do nothing and leave the node in place. |
318 } else if (canonical != node) { |
322 */ |
319 if (!canonical.isAlive()) { |
323 } else if (canonical != node) { |
320 assert !canonical.isDeleted(); |
324 if (!canonical.isAlive()) { |
321 canonical = graph.addOrUniqueWithInputs(canonical); |
325 assert !canonical.isDeleted(); |
322 } |
326 canonical = graph.addOrUniqueWithInputs(canonical); |
323 assert node.hasNoUsages(); |
327 } |
324 return canonical; |
328 assert node.hasNoUsages(); |
|
329 return canonical; |
|
330 } |
325 } |
331 } |
326 } |
332 } |
327 return node; |
333 return node; |
328 } |
334 } |
329 |
335 |