use of org.graalvm.compiler.nodes.AbstractDeoptimizeNode in project graal by oracle.
the class DeoptimizationGroupingPhase method run.
@Override
protected void run(StructuredGraph graph, MidTierContext context) {
ControlFlowGraph cfg = null;
for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
FixedNode target = null;
PhiNode reasonActionPhi = null;
PhiNode speculationPhi = null;
List<AbstractDeoptimizeNode> obsoletes = null;
for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) {
if (target == null) {
target = deopt;
} else {
if (cfg == null) {
cfg = ControlFlowGraph.compute(graph, true, true, false, false);
}
AbstractMergeNode merge;
if (target instanceof AbstractDeoptimizeNode) {
merge = graph.add(new MergeNode());
EndNode firstEnd = graph.add(new EndNode());
ValueNode actionAndReason = ((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess());
ValueNode speculation = ((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess());
reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge));
speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge));
merge.addForwardEnd(firstEnd);
reasonActionPhi.addInput(actionAndReason);
speculationPhi.addInput(speculation);
target.replaceAtPredecessor(firstEnd);
exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg);
merge.setNext(graph.add(new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi)));
obsoletes = new LinkedList<>();
obsoletes.add((AbstractDeoptimizeNode) target);
target = merge;
} else {
merge = (AbstractMergeNode) target;
}
EndNode newEnd = graph.add(new EndNode());
merge.addForwardEnd(newEnd);
reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess()));
speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess()));
deopt.replaceAtPredecessor(newEnd);
exitLoops(deopt, newEnd, cfg);
obsoletes.add(deopt);
}
}
if (obsoletes != null) {
((DynamicDeoptimizeNode) ((AbstractMergeNode) target).next()).setStateBefore(fs);
for (AbstractDeoptimizeNode obsolete : obsoletes) {
obsolete.safeDelete();
}
}
}
}
use of org.graalvm.compiler.nodes.AbstractDeoptimizeNode in project graal by oracle.
the class PropagateDeoptimizeProbabilityPhase method run.
@Override
@SuppressWarnings("try")
protected void run(final StructuredGraph graph, PhaseContext context) {
assert !graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
if (graph.hasNode(AbstractDeoptimizeNode.TYPE)) {
NodeStack stack = new NodeStack();
EconomicMap<ControlSplitNode, EconomicSet<AbstractBeginNode>> reachableSplits = EconomicMap.create();
// Mark all control flow nodes that are post-dominated by a deoptimization.
for (AbstractDeoptimizeNode d : graph.getNodes(AbstractDeoptimizeNode.TYPE)) {
stack.push(AbstractBeginNode.prevBegin(d));
while (!stack.isEmpty()) {
AbstractBeginNode beginNode = (AbstractBeginNode) stack.pop();
FixedNode fixedNode = (FixedNode) beginNode.predecessor();
if (fixedNode == null) {
// Can happen for start node.
} else if (fixedNode instanceof AbstractMergeNode) {
AbstractMergeNode mergeNode = (AbstractMergeNode) fixedNode;
for (AbstractEndNode end : mergeNode.forwardEnds()) {
AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(end);
stack.push(newBeginNode);
}
} else if (fixedNode instanceof ControlSplitNode) {
ControlSplitNode controlSplitNode = (ControlSplitNode) fixedNode;
EconomicSet<AbstractBeginNode> reachableSuccessors = reachableSplits.get(controlSplitNode);
if (reachableSuccessors == null) {
reachableSuccessors = EconomicSet.create();
reachableSplits.put(controlSplitNode, reachableSuccessors);
}
if (controlSplitNode.getSuccessorCount() == reachableSuccessors.size() - 1) {
// All successors of this split lead to deopt, propagate reachability
// further upwards.
reachableSplits.removeKey(controlSplitNode);
stack.push(AbstractBeginNode.prevBegin((FixedNode) controlSplitNode.predecessor()));
} else {
reachableSuccessors.add(beginNode);
}
} else {
stack.push(AbstractBeginNode.prevBegin(fixedNode));
}
}
}
// Make sure the probability on the path towards the deoptimization is 0.0.
MapCursor<ControlSplitNode, EconomicSet<AbstractBeginNode>> entries = reachableSplits.getEntries();
while (entries.advance()) {
ControlSplitNode controlSplitNode = entries.getKey();
EconomicSet<AbstractBeginNode> value = entries.getValue();
for (AbstractBeginNode begin : value) {
double probability = controlSplitNode.probability(begin);
if (probability != 0.0) {
controlSplitNode.setProbability(begin, 0.0);
}
}
}
}
}
use of org.graalvm.compiler.nodes.AbstractDeoptimizeNode in project graal by oracle.
the class DefaultHotSpotLoweringProvider method lower.
@Override
public void lower(Node n, LoweringTool tool) {
StructuredGraph graph = (StructuredGraph) n.graph();
if (n instanceof Invoke) {
lowerInvoke((Invoke) n, tool, graph);
} else if (n instanceof LoadMethodNode) {
lowerLoadMethodNode((LoadMethodNode) n);
} else if (n instanceof GetClassNode) {
lowerGetClassNode((GetClassNode) n, tool, graph);
} else if (n instanceof StoreHubNode) {
lowerStoreHubNode((StoreHubNode) n, graph);
} else if (n instanceof OSRStartNode) {
lowerOSRStartNode((OSRStartNode) n);
} else if (n instanceof BytecodeExceptionNode) {
lowerBytecodeExceptionNode((BytecodeExceptionNode) n);
} else if (n instanceof InstanceOfNode) {
InstanceOfNode instanceOfNode = (InstanceOfNode) n;
if (graph.getGuardsStage().areDeoptsFixed()) {
instanceofSnippets.lower(instanceOfNode, tool);
} else {
if (instanceOfNode.allowsNull()) {
ValueNode object = instanceOfNode.getValue();
LogicNode newTypeCheck = graph.addOrUniqueWithInputs(InstanceOfNode.create(instanceOfNode.type(), object, instanceOfNode.profile(), instanceOfNode.getAnchor()));
LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY);
instanceOfNode.replaceAndDelete(newNode);
}
}
} else if (n instanceof InstanceOfDynamicNode) {
InstanceOfDynamicNode instanceOfDynamicNode = (InstanceOfDynamicNode) n;
if (graph.getGuardsStage().areDeoptsFixed()) {
instanceofSnippets.lower(instanceOfDynamicNode, tool);
} else {
ValueNode mirror = instanceOfDynamicNode.getMirrorOrHub();
if (mirror.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object) {
ClassGetHubNode classGetHub = graph.unique(new ClassGetHubNode(mirror));
instanceOfDynamicNode.setMirror(classGetHub);
}
if (instanceOfDynamicNode.allowsNull()) {
ValueNode object = instanceOfDynamicNode.getObject();
LogicNode newTypeCheck = graph.addOrUniqueWithInputs(InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), instanceOfDynamicNode.getMirrorOrHub(), object, false));
LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY);
instanceOfDynamicNode.replaceAndDelete(newNode);
}
}
} else if (n instanceof ClassIsAssignableFromNode) {
if (graph.getGuardsStage().areDeoptsFixed()) {
instanceofSnippets.lower((ClassIsAssignableFromNode) n, tool);
}
} else if (n instanceof NewInstanceNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower((NewInstanceNode) n, registers, tool);
}
} else if (n instanceof DynamicNewInstanceNode) {
DynamicNewInstanceNode newInstanceNode = (DynamicNewInstanceNode) n;
if (newInstanceNode.getClassClass() == null) {
JavaConstant classClassMirror = constantReflection.forObject(Class.class);
ConstantNode classClass = ConstantNode.forConstant(classClassMirror, tool.getMetaAccess(), graph);
newInstanceNode.setClassClass(classClass);
}
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower(newInstanceNode, registers, tool);
}
} else if (n instanceof NewArrayNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower((NewArrayNode) n, registers, tool);
}
} else if (n instanceof DynamicNewArrayNode) {
DynamicNewArrayNode dynamicNewArrayNode = (DynamicNewArrayNode) n;
if (dynamicNewArrayNode.getVoidClass() == null) {
JavaConstant voidClassMirror = constantReflection.forObject(void.class);
ConstantNode voidClass = ConstantNode.forConstant(voidClassMirror, tool.getMetaAccess(), graph);
dynamicNewArrayNode.setVoidClass(voidClass);
}
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower(dynamicNewArrayNode, registers, tool);
}
} else if (n instanceof VerifyHeapNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower((VerifyHeapNode) n, registers, tool);
}
} else if (n instanceof RawMonitorEnterNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
monitorSnippets.lower((RawMonitorEnterNode) n, registers, tool);
}
} else if (n instanceof MonitorExitNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
monitorSnippets.lower((MonitorExitNode) n, registers, tool);
}
} else if (n instanceof ArrayCopyNode) {
arraycopySnippets.lower((ArrayCopyNode) n, tool);
} else if (n instanceof ArrayCopyWithSlowPathNode) {
arraycopySnippets.lower((ArrayCopyWithSlowPathNode) n, tool);
} else if (n instanceof G1PreWriteBarrier) {
writeBarrierSnippets.lower((G1PreWriteBarrier) n, registers, tool);
} else if (n instanceof G1PostWriteBarrier) {
writeBarrierSnippets.lower((G1PostWriteBarrier) n, registers, tool);
} else if (n instanceof G1ReferentFieldReadBarrier) {
writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, registers, tool);
} else if (n instanceof SerialWriteBarrier) {
writeBarrierSnippets.lower((SerialWriteBarrier) n, tool);
} else if (n instanceof SerialArrayRangeWriteBarrier) {
writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool);
} else if (n instanceof G1ArrayRangePreWriteBarrier) {
writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, registers, tool);
} else if (n instanceof G1ArrayRangePostWriteBarrier) {
writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, registers, tool);
} else if (n instanceof NewMultiArrayNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower((NewMultiArrayNode) n, tool);
}
} else if (n instanceof LoadExceptionObjectNode) {
exceptionObjectSnippets.lower((LoadExceptionObjectNode) n, registers, tool);
} else if (n instanceof AssertionNode) {
assertionSnippets.lower((AssertionNode) n, tool);
} else if (n instanceof StringToBytesNode) {
if (graph.getGuardsStage().areDeoptsFixed()) {
stringToBytesSnippets.lower((StringToBytesNode) n, tool);
}
} else if (n instanceof IntegerDivRemNode) {
// Nothing to do for division nodes. The HotSpot signal handler catches divisions by
// zero and the MIN_VALUE / -1 cases.
} else if (n instanceof AbstractDeoptimizeNode || n instanceof UnwindNode || n instanceof RemNode || n instanceof SafepointNode) {
/* No lowering, we generate LIR directly for these nodes. */
} else if (n instanceof ClassGetHubNode) {
lowerClassGetHubNode((ClassGetHubNode) n, tool);
} else if (n instanceof HubGetClassNode) {
lowerHubGetClassNode((HubGetClassNode) n, tool);
} else if (n instanceof KlassLayoutHelperNode) {
lowerKlassLayoutHelperNode((KlassLayoutHelperNode) n, tool);
} else if (n instanceof ComputeObjectAddressNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
lowerComputeObjectAddressNode((ComputeObjectAddressNode) n);
}
} else if (n instanceof IdentityHashCodeNode) {
hashCodeSnippets.lower((IdentityHashCodeNode) n, tool);
} else if (n instanceof ResolveDynamicConstantNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
resolveConstantSnippets.lower((ResolveDynamicConstantNode) n, tool);
}
} else if (n instanceof ResolveConstantNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
resolveConstantSnippets.lower((ResolveConstantNode) n, tool);
}
} else if (n instanceof ResolveMethodAndLoadCountersNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
resolveConstantSnippets.lower((ResolveMethodAndLoadCountersNode) n, tool);
}
} else if (n instanceof InitializeKlassNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
resolveConstantSnippets.lower((InitializeKlassNode) n, tool);
}
} else if (n instanceof ProfileNode) {
profileSnippets.lower((ProfileNode) n, tool);
} else {
super.lower(n, tool);
}
}
use of org.graalvm.compiler.nodes.AbstractDeoptimizeNode in project graal by oracle.
the class UseTrappingNullChecksPhase method checkPredecessor.
private static void checkPredecessor(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, long implicitNullCheckLimit) {
Node current = predecessor;
AbstractBeginNode branch = null;
while (current instanceof AbstractBeginNode) {
branch = (AbstractBeginNode) current;
if (branch.anchored().isNotEmpty()) {
// some input of the deopt framestate is anchored to this branch
return;
}
current = current.predecessor();
}
if (current instanceof IfNode) {
IfNode ifNode = (IfNode) current;
if (branch != ifNode.trueSuccessor()) {
return;
}
LogicNode condition = ifNode.condition();
if (condition instanceof IsNullNode) {
replaceWithTrappingNullCheck(deopt, ifNode, condition, deoptimizationReason, implicitNullCheckLimit);
}
}
}
Aggregations