use of org.graalvm.compiler.graph.Graph in project graal by oracle.
the class TypedNodeIteratorTest2 method simpleSubclassTest.
@Test
public void simpleSubclassTest() {
Graph graph = new Graph(getOptions(), getDebug());
graph.add(new NodeB("b"));
graph.add(new NodeD("d"));
Assert.assertEquals("bd", TypedNodeIteratorTest.toString(graph.getNodes(NodeB.TYPE)));
Assert.assertEquals("d", TypedNodeIteratorTest.toString(graph.getNodes(NodeD.TYPE)));
}
use of org.graalvm.compiler.graph.Graph in project graal by oracle.
the class LoopFragment method computeNodes.
protected static void computeNodes(NodeBitMap nodes, Graph graph, Iterable<AbstractBeginNode> blocks, Iterable<AbstractBeginNode> earlyExits) {
for (AbstractBeginNode b : blocks) {
if (b.isDeleted()) {
continue;
}
for (Node n : b.getBlockNodes()) {
if (n instanceof Invoke) {
nodes.mark(((Invoke) n).callTarget());
}
if (n instanceof NodeWithState) {
NodeWithState withState = (NodeWithState) n;
withState.states().forEach(state -> state.applyToVirtual(node -> nodes.mark(node)));
}
if (n instanceof AbstractMergeNode) {
// if a merge is in the loop, all of its phis are also in the loop
for (PhiNode phi : ((AbstractMergeNode) n).phis()) {
nodes.mark(phi);
}
}
nodes.mark(n);
}
}
for (AbstractBeginNode earlyExit : earlyExits) {
if (earlyExit.isDeleted()) {
continue;
}
nodes.mark(earlyExit);
if (earlyExit instanceof LoopExitNode) {
LoopExitNode loopExit = (LoopExitNode) earlyExit;
FrameState stateAfter = loopExit.stateAfter();
if (stateAfter != null) {
stateAfter.applyToVirtual(node -> nodes.mark(node));
}
for (ProxyNode proxy : loopExit.proxies()) {
nodes.mark(proxy);
}
}
}
final NodeBitMap nonLoopNodes = graph.createNodeBitMap();
Deque<WorkListEntry> worklist = new ArrayDeque<>();
for (AbstractBeginNode b : blocks) {
if (b.isDeleted()) {
continue;
}
for (Node n : b.getBlockNodes()) {
if (n instanceof CommitAllocationNode) {
for (VirtualObjectNode obj : ((CommitAllocationNode) n).getVirtualObjects()) {
markFloating(worklist, obj, nodes, nonLoopNodes);
}
}
if (n instanceof MonitorEnterNode) {
markFloating(worklist, ((MonitorEnterNode) n).getMonitorId(), nodes, nonLoopNodes);
}
if (n instanceof AbstractMergeNode) {
/*
* Since we already marked all phi nodes as being in the loop to break cycles,
* we also have to iterate over their usages here.
*/
for (PhiNode phi : ((AbstractMergeNode) n).phis()) {
for (Node usage : phi.usages()) {
markFloating(worklist, usage, nodes, nonLoopNodes);
}
}
}
for (Node usage : n.usages()) {
markFloating(worklist, usage, nodes, nonLoopNodes);
}
}
}
}
use of org.graalvm.compiler.graph.Graph in project graal by oracle.
the class ExpandLogicPhase method processConditional.
@SuppressWarnings("try")
private static void processConditional(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, ConditionalNode conditional) {
try (DebugCloseable context = conditional.withNodeSourcePosition()) {
ValueNode trueTarget = conditional.trueValue();
ValueNode falseTarget = conditional.falseValue();
Graph graph = conditional.graph();
ConditionalNode secondConditional = graph.unique(new ConditionalNode(y, yNegated ? falseTarget : trueTarget, yNegated ? trueTarget : falseTarget));
ConditionalNode firstConditional = graph.unique(new ConditionalNode(x, xNegated ? secondConditional : trueTarget, xNegated ? trueTarget : secondConditional));
conditional.replaceAndDelete(firstConditional);
}
}
use of org.graalvm.compiler.graph.Graph in project graal by oracle.
the class ExpandLogicPhase method processIf.
@SuppressWarnings("try")
private static void processIf(LogicNode x, boolean xNegated, LogicNode y, boolean yNegated, IfNode ifNode, double shortCircuitProbability) {
try (DebugCloseable context = ifNode.withNodeSourcePosition()) {
/*
* this method splits an IfNode, which has a ShortCircuitOrNode as its condition, into
* two separate IfNodes: if(X) and if(Y)
*
* for computing the probabilities P(X) and P(Y), we use two different approaches. The
* first one assumes that the shortCircuitProbability and the probability on the IfNode
* were created with each other in mind. If this assumption does not hold, we fall back
* to another mechanism for computing the probabilities.
*/
AbstractBeginNode trueTarget = ifNode.trueSuccessor();
AbstractBeginNode falseTarget = ifNode.falseSuccessor();
// 1st approach
// assumption: P(originalIf.trueSuccessor) == P(X) + ((1 - P(X)) * P(Y))
double firstIfTrueProbability = shortCircuitProbability;
double secondIfTrueProbability = sanitizeProbability((ifNode.getTrueSuccessorProbability() - shortCircuitProbability) / (1 - shortCircuitProbability));
double expectedOriginalIfTrueProbability = firstIfTrueProbability + (1 - firstIfTrueProbability) * secondIfTrueProbability;
if (!doubleEquals(ifNode.getTrueSuccessorProbability(), expectedOriginalIfTrueProbability)) {
/*
* 2nd approach
*
* the assumption above did not hold, so we either used an artificial probability as
* shortCircuitProbability or the ShortCircuitOrNode was moved to some other IfNode.
*
* so, we distribute the if's trueSuccessorProbability between the newly generated
* if nodes according to the shortCircuitProbability. the following invariant is
* always true in this case: P(originalIf.trueSuccessor) == P(X) + ((1 - P(X)) *
* P(Y))
*/
firstIfTrueProbability = ifNode.getTrueSuccessorProbability() * shortCircuitProbability;
secondIfTrueProbability = sanitizeProbability(1 - (ifNode.probability(falseTarget) / (1 - firstIfTrueProbability)));
}
ifNode.clearSuccessors();
Graph graph = ifNode.graph();
AbstractMergeNode trueTargetMerge = graph.add(new MergeNode());
trueTargetMerge.setNext(trueTarget);
EndNode firstTrueEnd = graph.add(new EndNode());
EndNode secondTrueEnd = graph.add(new EndNode());
trueTargetMerge.addForwardEnd(firstTrueEnd);
trueTargetMerge.addForwardEnd(secondTrueEnd);
AbstractBeginNode firstTrueTarget = BeginNode.begin(firstTrueEnd);
AbstractBeginNode secondTrueTarget = BeginNode.begin(secondTrueEnd);
if (yNegated) {
secondIfTrueProbability = 1.0 - secondIfTrueProbability;
}
if (xNegated) {
firstIfTrueProbability = 1.0 - firstIfTrueProbability;
}
AbstractBeginNode secondIf = BeginNode.begin(graph.add(new IfNode(y, yNegated ? falseTarget : secondTrueTarget, yNegated ? secondTrueTarget : falseTarget, secondIfTrueProbability)));
IfNode firstIf = graph.add(new IfNode(x, xNegated ? secondIf : firstTrueTarget, xNegated ? firstTrueTarget : secondIf, firstIfTrueProbability));
ifNode.replaceAtPredecessor(firstIf);
ifNode.safeDelete();
}
}
use of org.graalvm.compiler.graph.Graph in project graal by oracle.
the class LoopPartialUnrollPhase method run.
@Override
@SuppressWarnings("try")
protected void run(StructuredGraph graph, PhaseContext context) {
if (graph.hasLoops()) {
HashSetNodeEventListener listener = new HashSetNodeEventListener();
boolean changed = true;
while (changed) {
changed = false;
try (Graph.NodeEventScope nes = graph.trackNodeEvents(listener)) {
LoopsData dataCounted = new LoopsData(graph);
dataCounted.detectedCountedLoops();
Graph.Mark mark = graph.getMark();
boolean prePostInserted = false;
for (LoopEx loop : dataCounted.countedLoops()) {
if (!LoopTransformations.isUnrollableLoop(loop)) {
continue;
}
if (getPolicies().shouldPartiallyUnroll(loop)) {
if (loop.loopBegin().isSimpleLoop()) {
// First perform the pre/post transformation and do the partial
// unroll when we come around again.
LoopTransformations.insertPrePostLoops(loop);
prePostInserted = true;
} else {
LoopTransformations.partialUnroll(loop);
}
changed = true;
}
}
dataCounted.deleteUnusedNodes();
if (!listener.getNodes().isEmpty()) {
canonicalizer.applyIncremental(graph, context, listener.getNodes());
listener.getNodes().clear();
}
assert !prePostInserted || checkCounted(graph, mark);
}
}
}
}
Aggregations