use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class SPARCIntegerCompareCanonicalizationPhase method run.
@Override
protected void run(StructuredGraph graph) {
for (Node n : graph.getNodes()) {
if (n instanceof CompareNode) {
CompareNode enode = (CompareNode) n;
min32(enode, enode.getX());
min32(enode, enode.getY());
}
}
}
use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class GraphScheduleTest method assertOrderedAfterSchedule.
protected void assertOrderedAfterSchedule(ScheduleResult ibp, Node a, Node b) {
NodeMap<Block> nodeToBlock = ibp.getCFG().getNodeToBlock();
Block bBlock = nodeToBlock.get(b);
Block aBlock = nodeToBlock.get(a);
if (bBlock == aBlock) {
List<Node> instructions = ibp.nodesFor(bBlock);
Assert.assertTrue(a + " should be before " + b, instructions.indexOf(b) > instructions.indexOf(a));
} else {
Block block = bBlock;
while (block != null) {
if (block == aBlock) {
return;
}
block = block.getDominator();
}
Assert.fail("block of A doesn't dominate the block of B");
}
}
use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class FloatingReadTest method test.
@SuppressWarnings("try")
private void test(final String snippet) {
DebugContext debug = getDebugContext();
try (DebugContext.Scope s = debug.scope("FloatingReadTest", new DebugDumpScope(snippet))) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
PhaseContext context = new PhaseContext(getProviders());
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
new FloatingReadPhase().apply(graph);
ReturnNode returnNode = null;
MonitorExit monitorexit = null;
for (Node n : graph.getNodes()) {
if (n instanceof ReturnNode) {
assert returnNode == null;
returnNode = (ReturnNode) n;
} else if (n instanceof MonitorExit) {
monitorexit = (MonitorExit) n;
}
}
debug.dump(DebugContext.BASIC_LEVEL, graph, "After lowering");
Assert.assertNotNull(returnNode);
Assert.assertNotNull(monitorexit);
Assert.assertTrue(returnNode.result() instanceof FloatingReadNode);
FloatingReadNode read = (FloatingReadNode) returnNode.result();
assertOrderedAfterSchedule(graph, read, (Node) monitorexit);
} catch (Throwable e) {
throw debug.handle(e);
}
}
use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class LoopDetector method ensureNodeCreated.
protected Node ensureNodeCreated(MethodScope methodScope, LoopScope loopScope, int nodeOrderId) {
if (nodeOrderId == GraphEncoder.NULL_ORDER_ID) {
return null;
}
Node node = lookupNode(loopScope, nodeOrderId);
if (node != null) {
return node;
}
node = decodeFloatingNode(methodScope, loopScope, nodeOrderId);
if (node instanceof ProxyNode || node instanceof PhiNode) {
/*
* We need these nodes as they were in the original graph, without any canonicalization
* or value numbering.
*/
node = graph.addWithoutUnique(node);
} else {
/* Allow subclasses to canonicalize and intercept nodes. */
Node newNode = handleFloatingNodeBeforeAdd(methodScope, loopScope, node);
if (newNode != node) {
releaseFloatingNode(node);
}
if (!newNode.isAlive()) {
newNode = addFloatingNode(methodScope, newNode);
}
node = handleFloatingNodeAfterAdd(methodScope, loopScope, newNode);
}
registerNode(loopScope, nodeOrderId, node, false, false);
return node;
}
use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class LoopDetector method findLoops.
private List<Loop> findLoops() {
/* Mapping from the loop header node to additional loop information. */
EconomicMap<MergeNode, Loop> unorderedLoops = EconomicMap.create(Equivalence.IDENTITY);
/* Loops in reverse order of, i.e., inner loops before outer loops. */
List<Loop> orderedLoops = new ArrayList<>();
/*
* Ensure we have an outermost loop that we can use to eliminate irreducible loops. This
* loop can remain empty (no ends), in which case it is ignored.
*/
irreducibleLoopHandler = findOrCreateLoop(unorderedLoops, methodScope.loopExplosionHead);
NodeBitMap visited = graph.createNodeBitMap();
NodeBitMap active = graph.createNodeBitMap();
Deque<Node> stack = new ArrayDeque<>();
visited.mark(methodScope.loopExplosionHead);
stack.push(methodScope.loopExplosionHead);
while (!stack.isEmpty()) {
Node current = stack.peek();
assert visited.isMarked(current);
if (active.isMarked(current)) {
/* We are back-tracking, i.e., all successor nodes have been processed. */
stack.pop();
active.clear(current);
if (current instanceof MergeNode) {
Loop loop = unorderedLoops.get((MergeNode) current);
if (loop != null) {
/*
* Since nodes are popped in reverse order that they were pushed, we add
* inner loops before outer loops here.
*/
assert !orderedLoops.contains(loop);
orderedLoops.add(loop);
}
}
} else {
/*
* Process the node. Note that we do not remove the node from the stack, i.e., we
* will peek it again. But the next time the node is marked as active, so we do not
* execute this code again.
*/
active.mark(current);
for (Node successor : current.cfgSuccessors()) {
if (active.isMarked(successor)) {
/* Detected a cycle, i.e., a backward branch of a loop. */
Loop loop = findOrCreateLoop(unorderedLoops, (MergeNode) successor);
assert !loop.ends.contains(current);
loop.ends.add((EndNode) current);
} else if (visited.isMarked(successor)) {
/* Forward merge into a branch we are already exploring. */
} else {
/* Forward branch to a node we have not seen yet. */
visited.mark(successor);
stack.push(successor);
}
}
}
}
return orderedLoops;
}
Aggregations