private StructuredGraph parseAndProcess(String snippet) { StructuredGraph graph = parse(snippet); LocalNode local = graph.getNodes(LocalNode.class).first(); ConstantNode constant = ConstantNode.forInt(0, graph); for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) { n.replaceFirstInput(local, constant); } Map<Invoke, Double> hints = new HashMap<>(); for (Invoke invoke : graph.getInvokes()) { hints.put(invoke, 1000d); } Assumptions assumptions = new Assumptions(false); new InliningPhase( runtime(), hints, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL) .apply(graph); new CanonicalizerPhase.Instance(runtime(), assumptions, true).apply(graph); new DeadCodeEliminationPhase().apply(graph); return graph; }
public static boolean tryKillUnused(Node node) { if (node.isAlive() && isFloatingNode().apply(node) && node.usages().isEmpty()) { killWithUnusedFloatingInputs(node); return true; } return false; }
public static void killWithUnusedFloatingInputs(Node node) { List<Node> floatingInputs = node.inputs().filter(isFloatingNode()).snapshot(); node.safeDelete(); for (Node in : floatingInputs) { if (in.isAlive() && in.usages().isEmpty()) { killWithUnusedFloatingInputs(in); } } }
public static void killCFG(Node node, SimplifierTool tool) { assert node.isAlive(); if (node instanceof AbstractEndNode) { // We reached a control flow end. AbstractEndNode end = (AbstractEndNode) node; killEnd(end, tool); } else { // Normal control flow node. /* * We do not take a successor snapshot because this iterator supports concurrent * modifications as long as they do not change the size of the successor list. Not * taking a snapshot allows us to see modifications to other branches that may happen * while processing one branch. */ for (Node successor : node.successors()) { killCFG(successor, tool); } } propagateKill(node); }
/** * Gets an approximate source code location for a node if possible. * * @return the StackTraceElements if an approximate source location is found, null otherwise */ public static StackTraceElement[] approxSourceStackTraceElement(Node node) { ArrayList<StackTraceElement> elements = new ArrayList<>(); Node n = node; while (n != null) { if (n instanceof MethodCallTargetNode) { elements.add(((MethodCallTargetNode) n).targetMethod().asStackTraceElement(-1)); n = ((MethodCallTargetNode) n).invoke().asNode(); } if (n instanceof StateSplit) { FrameState state = ((StateSplit) n).stateAfter(); while (state != null) { ResolvedJavaMethod method = state.method(); if (method != null) { elements.add(method.asStackTraceElement(state.bci - 1)); } state = state.outerFrameState(); } break; } n = n.predecessor(); } return elements.toArray(new StackTraceElement[elements.size()]); }
public static void propagateKill(Node node) { if (node != null && node.isAlive()) { List<Node> usagesSnapshot = node.usages().filter(isFloatingNode()).snapshot(); // null out remaining usages node.replaceAtUsages(null); node.replaceAtPredecessor(null); killWithUnusedFloatingInputs(node); for (Node usage : usagesSnapshot) { if (!usage.isDeleted()) { if (usage instanceof PhiNode) { usage.replaceFirstInput(node, null); } else { propagateKill(usage); } } } } }
public void deleteBranch(Node branch) { branch.predecessor().replaceFirstSuccessor(branch, null); GraphUtil.killCFG(branch, this); }