use of org.graalvm.compiler.nodes.ProxyNode in project graal by oracle.
the class GraphUtil method checkRedundantPhi.
public static void checkRedundantPhi(PhiNode phiNode) {
if (phiNode.isDeleted() || phiNode.valueCount() == 1) {
return;
}
ValueNode singleValue = phiNode.singleValueOrThis();
if (singleValue != phiNode) {
Collection<PhiNode> phiUsages = phiNode.usages().filter(PhiNode.class).snapshot();
Collection<ProxyNode> proxyUsages = phiNode.usages().filter(ProxyNode.class).snapshot();
phiNode.replaceAtUsagesAndDelete(singleValue);
for (PhiNode phi : phiUsages) {
checkRedundantPhi(phi);
}
for (ProxyNode proxy : proxyUsages) {
checkRedundantProxy(proxy);
}
}
}
use of org.graalvm.compiler.nodes.ProxyNode in project graal by oracle.
the class EarlyReadEliminationTest method testBadLoop.
@Test
public void testBadLoop() {
ValueNode result = getReturn("testBadLoopSnippet", false).result();
assertDeepEquals(0, result.graph().getNodes().filter(LoadFieldNode.class).count());
assertTrue(result instanceof ProxyNode);
assertTrue(((ProxyNode) result).value() instanceof ValuePhiNode);
}
use of org.graalvm.compiler.nodes.ProxyNode in project graal by oracle.
the class LoopFragmentInside method patchPeeling.
private void patchPeeling(LoopFragmentInside peel) {
LoopBeginNode loopBegin = loop().loopBegin();
StructuredGraph graph = loopBegin.graph();
List<PhiNode> newPhis = new LinkedList<>();
NodeBitMap usagesToPatch = nodes.copy();
for (LoopExitNode exit : exits()) {
markStateNodes(exit, usagesToPatch);
for (ProxyNode proxy : exit.proxies()) {
usagesToPatch.markAndGrow(proxy);
}
}
markStateNodes(loopBegin, usagesToPatch);
List<PhiNode> oldPhis = loopBegin.phis().snapshot();
for (PhiNode phi : oldPhis) {
if (phi.hasNoUsages()) {
continue;
}
ValueNode first;
if (loopBegin.loopEnds().count() == 1) {
// back edge value
ValueNode b = phi.valueAt(loopBegin.loopEnds().first());
// corresponding value in the peel
first = peel.prim(b);
} else {
first = peel.mergedInitializers.get(phi);
}
// create a new phi (we don't patch the old one since some usages of the old one may
// still be valid)
PhiNode newPhi = patchPhi(graph, phi, loopBegin);
newPhi.addInput(first);
for (LoopEndNode end : loopBegin.orderedLoopEnds()) {
newPhi.addInput(phi.valueAt(end));
}
peel.putDuplicatedNode(phi, newPhi);
newPhis.add(newPhi);
for (Node usage : phi.usages().snapshot()) {
// patch only usages that should use the new phi ie usages that were peeled
if (usagesToPatch.isMarkedAndGrow(usage)) {
usage.replaceFirstInput(phi, newPhi);
}
}
}
// new corresponding phis
for (PhiNode phi : newPhis) {
for (int i = 0; i < phi.valueCount(); i++) {
ValueNode v = phi.valueAt(i);
if (loopBegin.isPhiAtMerge(v)) {
PhiNode newV = peel.getDuplicatedNode((ValuePhiNode) v);
if (newV != null) {
phi.setValueAt(i, newV);
}
}
}
}
boolean progress = true;
while (progress) {
progress = false;
int i = 0;
outer: while (i < oldPhis.size()) {
PhiNode oldPhi = oldPhis.get(i);
for (Node usage : oldPhi.usages()) {
if (usage instanceof PhiNode && oldPhis.contains(usage)) {
// Do not mark.
} else {
// Mark alive by removing from delete set.
oldPhis.remove(i);
progress = true;
continue outer;
}
}
i++;
}
}
for (PhiNode deadPhi : oldPhis) {
deadPhi.clearInputs();
}
for (PhiNode deadPhi : oldPhis) {
if (deadPhi.isAlive()) {
GraphUtil.killWithUnusedFloatingInputs(deadPhi);
}
}
}
use of org.graalvm.compiler.nodes.ProxyNode in project graal by oracle.
the class BinaryGraphPrinter method nodeProperties.
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public void nodeProperties(GraphInfo info, Node node, Map<String, Object> props) {
node.getDebugProperties((Map) props);
Graph graph = info.graph;
ControlFlowGraph cfg = info.cfg;
NodeMap<Block> nodeToBlocks = info.nodeToBlocks;
if (cfg != null && DebugOptions.PrintGraphProbabilities.getValue(graph.getOptions()) && node instanceof FixedNode) {
try {
props.put("probability", cfg.blockFor(node).probability());
} catch (Throwable t) {
props.put("probability", 0.0);
props.put("probability-exception", t);
}
}
try {
props.put("NodeCost-Size", node.estimatedNodeSize());
props.put("NodeCost-Cycles", node.estimatedNodeCycles());
} catch (Throwable t) {
props.put("node-cost-exception", t.getMessage());
}
if (nodeToBlocks != null) {
Object block = getBlockForNode(node, nodeToBlocks);
if (block != null) {
props.put("node-to-block", block);
}
}
if (node instanceof ControlSinkNode) {
props.put("category", "controlSink");
} else if (node instanceof ControlSplitNode) {
props.put("category", "controlSplit");
} else if (node instanceof AbstractMergeNode) {
props.put("category", "merge");
} else if (node instanceof AbstractBeginNode) {
props.put("category", "begin");
} else if (node instanceof AbstractEndNode) {
props.put("category", "end");
} else if (node instanceof FixedNode) {
props.put("category", "fixed");
} else if (node instanceof VirtualState) {
props.put("category", "state");
} else if (node instanceof PhiNode) {
props.put("category", "phi");
} else if (node instanceof ProxyNode) {
props.put("category", "proxy");
} else {
if (node instanceof ConstantNode) {
ConstantNode cn = (ConstantNode) node;
updateStringPropertiesForConstant((Map) props, cn);
}
props.put("category", "floating");
}
if (getSnippetReflectionProvider() != null) {
for (Map.Entry<String, Object> prop : props.entrySet()) {
if (prop.getValue() instanceof JavaConstantFormattable) {
props.put(prop.getKey(), ((JavaConstantFormattable) prop.getValue()).format(this));
}
}
}
}
use of org.graalvm.compiler.nodes.ProxyNode in project graal by oracle.
the class CanonicalStringGraphPrinter method writeCanonicalGraphString.
protected static void writeCanonicalGraphString(StructuredGraph graph, boolean excludeVirtual, boolean checkConstants, PrintWriter writer) {
StructuredGraph.ScheduleResult scheduleResult = GraphPrinter.getScheduleOrNull(graph);
if (scheduleResult == null) {
return;
}
try {
NodeMap<Integer> canonicalId = graph.createNodeMap();
int nextId = 0;
List<String> constantsLines = null;
if (checkConstants) {
constantsLines = new ArrayList<>();
}
for (Block block : scheduleResult.getCFG().getBlocks()) {
writer.print("Block ");
writer.print(block);
writer.print(" ");
if (block == scheduleResult.getCFG().getStartBlock()) {
writer.print("* ");
}
writer.print("-> ");
for (Block successor : block.getSuccessors()) {
writer.print(successor);
writer.print(" ");
}
writer.println();
for (Node node : scheduleResult.getBlockToNodesMap().get(block)) {
if (node instanceof ValueNode && node.isAlive()) {
if (!excludeVirtual || !(node instanceof VirtualObjectNode || node instanceof ProxyNode || node instanceof FullInfopointNode)) {
if (node instanceof ConstantNode) {
if (constantsLines != null) {
String name = node.toString(Verbosity.Name);
String str = name + (excludeVirtual ? "" : " (" + filteredUsageCount(node) + ")");
constantsLines.add(str);
}
} else {
int id;
if (canonicalId.get(node) != null) {
id = canonicalId.get(node);
} else {
id = nextId++;
canonicalId.set(node, id);
}
String name = node.getClass().getSimpleName();
writer.print(" ");
writer.print(id);
writer.print("|");
writer.print(name);
if (!excludeVirtual) {
writer.print(" (");
writer.print(filteredUsageCount(node));
writer.print(")");
}
writer.println();
}
}
}
}
}
if (constantsLines != null) {
writer.print(constantsLines.size());
writer.println(" constants:");
Collections.sort(constantsLines);
for (String s : constantsLines) {
writer.println(s);
}
}
} catch (Throwable t) {
writer.println();
t.printStackTrace(writer);
}
}
Aggregations