use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class MethodCallTargetNode method tryCheckCastSingleImplementor.
private boolean tryCheckCastSingleImplementor(ValueNode receiver, TypeReference speculatedType) {
ResolvedJavaType singleImplementor = speculatedType.getType();
if (singleImplementor != null) {
ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveConcreteMethod(targetMethod(), invoke().getContextType());
if (singleImplementorMethod != null) {
/**
* We have an invoke on an interface with a single implementor. We can replace this
* with an invoke virtual.
*
* To do so we need to ensure two properties: 1) the receiver must implement the
* interface (declaredReceiverType). The verifier does not prove this so we need a
* dynamic check. 2) we need to ensure that there is still only one implementor of
* this interface, i.e. that we are calling the right method. We could do this with
* an assumption but as we need an instanceof check anyway we can verify both
* properties by checking of the receiver is an instance of the single implementor.
*/
ValueAnchorNode anchor = new ValueAnchorNode(null);
if (anchor != null) {
graph().add(anchor);
graph().addBeforeFixed(invoke().asNode(), anchor);
}
LogicNode condition = graph().addOrUniqueWithInputs(InstanceOfNode.create(speculatedType, receiver, getProfile(), anchor));
FixedGuardNode guard = graph().add(new FixedGuardNode(condition, DeoptimizationReason.OptimizedTypeCheckViolated, DeoptimizationAction.InvalidateRecompile, false));
graph().addBeforeFixed(invoke().asNode(), guard);
ValueNode valueNode = graph().addOrUnique(new PiNode(receiver, StampFactory.objectNonNull(speculatedType), guard));
arguments().set(0, valueNode);
if (speculatedType.isExact()) {
setInvokeKind(InvokeKind.Special);
} else {
setInvokeKind(InvokeKind.Virtual);
}
setTargetMethod(singleImplementorMethod);
return true;
}
}
return false;
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class ConvertDeoptimizeToGuardPhase method propagateFixed.
@SuppressWarnings("try")
private void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, LoweringProvider loweringProvider) {
Node current = from;
while (current != null) {
if (GraalOptions.GuardPriorities.getValue(from.getOptions()) && current instanceof FixedGuardNode) {
FixedGuardNode otherGuard = (FixedGuardNode) current;
if (otherGuard.computePriority().isHigherPriorityThan(deopt.computePriority())) {
moveAsDeoptAfter(otherGuard, deopt);
return;
}
} else if (current instanceof AbstractBeginNode) {
if (current instanceof AbstractMergeNode) {
AbstractMergeNode mergeNode = (AbstractMergeNode) current;
FixedNode next = mergeNode.next();
while (mergeNode.isAlive()) {
AbstractEndNode end = mergeNode.forwardEnds().first();
propagateFixed(end, deopt, loweringProvider);
}
assert next.isAlive();
propagateFixed(next, deopt, loweringProvider);
return;
} else if (current.predecessor() instanceof IfNode) {
IfNode ifNode = (IfNode) current.predecessor();
// Prioritize the source position of the IfNode
try (DebugCloseable closable = ifNode.withNodeSourcePosition()) {
StructuredGraph graph = ifNode.graph();
LogicNode conditionNode = ifNode.condition();
boolean negateGuardCondition = current == ifNode.trueSuccessor();
FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.getReason(), deopt.getAction(), deopt.getSpeculation(), negateGuardCondition));
FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
AbstractBeginNode survivingSuccessor;
if (negateGuardCondition) {
survivingSuccessor = ifNode.falseSuccessor();
} else {
survivingSuccessor = ifNode.trueSuccessor();
}
graph.removeSplitPropagate(ifNode, survivingSuccessor);
Node newGuard = guard;
if (survivingSuccessor instanceof LoopExitNode) {
newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor, graph);
}
survivingSuccessor.replaceAtUsages(InputType.Guard, newGuard);
graph.getDebug().log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", negateGuardCondition, ifNode, survivingSuccessor);
FixedNode next = pred.next();
pred.setNext(guard);
guard.setNext(next);
SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(null, null, null, false, graph.getAssumptions(), graph.getOptions(), loweringProvider);
survivingSuccessor.simplify(simplifierTool);
return;
}
} else if (current.predecessor() == null || current.predecessor() instanceof ControlSplitNode) {
assert current.predecessor() != null || (current instanceof StartNode && current == ((AbstractBeginNode) current).graph().start());
moveAsDeoptAfter((AbstractBeginNode) current, deopt);
return;
}
}
current = current.predecessor();
}
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class ConvertDeoptimizeToGuardPhase method trySplitFixedGuard.
private void trySplitFixedGuard(FixedGuardNode fixedGuard, PhaseContext context) {
LogicNode condition = fixedGuard.condition();
if (condition instanceof CompareNode) {
CompareNode compare = (CompareNode) condition;
ValueNode x = compare.getX();
ValuePhiNode xPhi = (x instanceof ValuePhiNode) ? (ValuePhiNode) x : null;
if (x instanceof ConstantNode || xPhi != null) {
ValueNode y = compare.getY();
ValuePhiNode yPhi = (y instanceof ValuePhiNode) ? (ValuePhiNode) y : null;
if (y instanceof ConstantNode || yPhi != null) {
processFixedGuardAndPhis(fixedGuard, context, compare, x, xPhi, y, yPhi);
}
}
}
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class ExpandLogicPhase method processNormalizeCompareNode.
private static void processNormalizeCompareNode(NormalizeCompareNode normalize) {
LogicNode equalComp;
LogicNode lessComp;
StructuredGraph graph = normalize.graph();
ValueNode x = normalize.getX();
ValueNode y = normalize.getY();
if (x.stamp(NodeView.DEFAULT) instanceof FloatStamp) {
equalComp = graph.addOrUniqueWithInputs(FloatEqualsNode.create(x, y, NodeView.DEFAULT));
lessComp = graph.addOrUniqueWithInputs(FloatLessThanNode.create(x, y, normalize.isUnorderedLess(), NodeView.DEFAULT));
} else {
equalComp = graph.addOrUniqueWithInputs(IntegerEqualsNode.create(x, y, NodeView.DEFAULT));
lessComp = graph.addOrUniqueWithInputs(IntegerLessThanNode.create(x, y, NodeView.DEFAULT));
}
Stamp stamp = normalize.stamp(NodeView.DEFAULT);
ConditionalNode equalValue = graph.unique(new ConditionalNode(equalComp, ConstantNode.forIntegerStamp(stamp, 0, graph), ConstantNode.forIntegerStamp(stamp, 1, graph)));
ConditionalNode value = graph.unique(new ConditionalNode(lessComp, ConstantNode.forIntegerStamp(stamp, -1, graph), equalValue));
normalize.replaceAtUsagesAndDelete(value);
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class LoopTransformations method updatePreLoopLimit.
private static void updatePreLoopLimit(IfNode preLimit, InductionVariable preIv, CountedLoopInfo preCounted) {
// Update the pre loops limit test
StructuredGraph graph = preLimit.graph();
LogicNode ifTest = preLimit.condition();
CompareNode compareNode = (CompareNode) ifTest;
ValueNode prePhi = preIv.valueNode();
// Make new limit one iteration
ValueNode initIv = preCounted.getStart();
ValueNode newLimit = add(graph, initIv, preIv.strideNode());
// Fetch the variable we are not replacing and configure the one we are
ValueNode ub;
if (compareNode.getX() == prePhi) {
ub = compareNode.getY();
} else if (compareNode.getY() == prePhi) {
ub = compareNode.getX();
} else {
throw GraalError.shouldNotReachHere();
}
// Re-wire the condition with the new limit
if (preIv.direction() == Direction.Up) {
compareNode.replaceFirstInput(ub, graph.unique(new ConditionalNode(graph.unique(new IntegerLessThanNode(newLimit, ub)), newLimit, ub)));
} else {
compareNode.replaceFirstInput(ub, graph.unique(new ConditionalNode(graph.unique(new IntegerLessThanNode(ub, newLimit)), newLimit, ub)));
}
}
Aggregations