public static void normalizeLoopBegin(LoopBeginNode begin) { // Delete unnecessary loop phi functions, i.e., phi functions where all inputs are either // the same or the phi itself. for (PhiNode phi : begin.phis().snapshot()) { GraphUtil.checkRedundantPhi(phi); } for (LoopExitNode exit : begin.loopExits()) { for (ProxyNode vpn : exit.proxies().snapshot()) { GraphUtil.checkRedundantProxy(vpn); } } }
/** * This method performs two kinds of cleanup: * * <ol> * <li>marking as unreachable certain code-paths, as described in {@link * com.oracle.graal.phases.common.cfs.BaseReduction.PostponedDeopt} * <li>Removing nodes not in use that were added during this phase, as described next. * </ol> * * <p>Methods like {@link * com.oracle.graal.phases.common.cfs.FlowUtil#replaceInPlace(com.oracle.graal.graph.Node, * com.oracle.graal.graph.Node, com.oracle.graal.graph.Node)} may result in old inputs becoming * disconnected from the graph. It's not advisable to {@link * com.oracle.graal.nodes.util.GraphUtil#tryKillUnused(com.oracle.graal.graph.Node)} at that * moment, because one of the inputs that might get killed is one of {@link #nullConstant}, {@link * #falseConstant}, or {@link #trueConstant}; which thus could get killed too early, before * another invocation of {@link * com.oracle.graal.phases.common.cfs.EquationalReasoner#deverbosify(com.oracle.graal.graph.Node)} * needs them. To recap, {@link * com.oracle.graal.nodes.util.GraphUtil#tryKillUnused(com.oracle.graal.graph.Node)} also * recursively visits the inputs of the its argument. * * <p>This method goes over all of the nodes that deverbosification might have added, which are * either: * * <ul> * <li>{@link com.oracle.graal.nodes.calc.FloatingNode}, added by {@link * com.oracle.graal.phases.common.cfs.EquationalReasoner#deverbosifyFloatingNode(com.oracle.graal.nodes.calc.FloatingNode)} * ; or * <li>{@link com.oracle.graal.nodes.java.MethodCallTargetNode}, added by {@link * #deverbosifyInputsCopyOnWrite(com.oracle.graal.nodes.java.MethodCallTargetNode)} * </ul> * * Checking if they aren't in use, proceeding to remove them in that case. */ @Override public void finished() { if (!postponedDeopts.isEmpty()) { for (PostponedDeopt postponed : postponedDeopts) { postponed.doRewrite(falseConstant); } new DeadCodeEliminationPhase(Optional).apply(graph); } for (MethodCallTargetNode mcn : graph.getNodes().filter(MethodCallTargetNode.class)) { if (mcn.isAlive() && FlowUtil.lacksUsages(mcn)) { mcn.safeDelete(); } } for (Node n : graph.getNodes().filter(FloatingNode.class)) { GraphUtil.tryKillUnused(n); } assert !isAliveWithoutUsages(trueConstant); assert !isAliveWithoutUsages(falseConstant); assert !isAliveWithoutUsages(nullConstant); super.finished(); }
public void removeIfUnused(Node node) { GraphUtil.tryKillUnused(node); }
public void deleteBranch(Node branch) { branch.predecessor().replaceFirstSuccessor(branch, null); GraphUtil.killCFG(branch, this); }