use of org.graalvm.compiler.nodes.PiNode in project graal by oracle.
the class CInterfaceEnumTool method replaceEnumLookupInvoke.
boolean replaceEnumLookupInvoke(BytecodeParser p, EnumInfo enumInfo, ResolvedJavaMethod method, ValueNode[] args) {
assert Modifier.isStatic(method.getModifiers()) && method.getSignature().getParameterCount(false) == 1;
assert args.length == 1;
JavaKind methodParameterKind = method.getSignature().getParameterType(0, null).getJavaKind();
InvokeNode invokeNode = invokeEnumLookup(p, CallTargetFactory.from(p), p.getFrameStateBuilder(), p.bci(), enumInfo, methodParameterKind, args[0]);
Stamp returnStamp = p.getInvokeReturnStamp(null).getTrustedStamp();
assert returnStamp.getStackKind() == JavaKind.Object && invokeNode.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object;
assert StampTool.typeOrNull(invokeNode.stamp(NodeView.DEFAULT)).isAssignableFrom(StampTool.typeOrNull(returnStamp));
ValueNode adapted = p.getGraph().unique(new PiNode(invokeNode, returnStamp));
p.push(CInterfaceInvocationPlugin.pushKind(method), adapted);
return true;
}
use of org.graalvm.compiler.nodes.PiNode in project graal by oracle.
the class DevirtualizeCallsPhase method singleCallee.
private static void singleCallee(HostedMethod singleCallee, StructuredGraph graph, Invoke invoke, SubstrateMethodCallTargetNode callTarget) {
/*
* The invoke has only one callee, i.e., the call can be devirtualized to this callee. This
* allows later inlining of the callee.
*
* We have to be careful to guard the improvement of the receiver type that is implied by
* the devirtualization: The callee assumes that the receiver type is the type that declares
* the callee. While this is true for all parts of the callee, it does not necessarily hold
* for all parts of the caller. So we need to ensure that after a possible inlining no parts
* of the callee float out to parts of the caller where the receiver type assumption does
* not hold. Since we do not know where in the caller a possible type check is performed, we
* anchor the receiver to the place of the original invoke.
*/
ValueAnchorNode anchor = graph.add(new ValueAnchorNode(null));
graph.addBeforeFixed(invoke.asNode(), anchor);
Stamp anchoredReceiverStamp = StampFactory.object(TypeReference.createWithoutAssumptions(singleCallee.getDeclaringClass()));
ValueNode anchoredReceiver = graph.unique(new PiNode(invoke.getReceiver(), anchoredReceiverStamp, anchor));
invoke.callTarget().replaceFirstInput(invoke.getReceiver(), anchoredReceiver);
assert callTarget.invokeKind() == InvokeKind.Virtual || callTarget.invokeKind() == InvokeKind.Interface;
callTarget.setInvokeKind(InvokeKind.Special);
callTarget.setTargetMethod(singleCallee);
}
use of org.graalvm.compiler.nodes.PiNode in project graal by oracle.
the class LoopEx method findInductionVariables.
/**
* Collect all the basic induction variables for the loop and the find any induction variables
* which are derived from the basic ones.
*
* @param loop
* @return a map from node to induction variable
*/
private static EconomicMap<Node, InductionVariable> findInductionVariables(LoopEx loop) {
EconomicMap<Node, InductionVariable> ivs = EconomicMap.create(Equivalence.IDENTITY);
Queue<InductionVariable> scanQueue = new LinkedList<>();
LoopBeginNode loopBegin = loop.loopBegin();
AbstractEndNode forwardEnd = loopBegin.forwardEnd();
for (PhiNode phi : loopBegin.valuePhis()) {
ValueNode backValue = phi.singleBackValueOrThis();
if (backValue == phi) {
continue;
}
ValueNode stride = addSub(loop, backValue, phi);
if (stride != null) {
BasicInductionVariable biv = new BasicInductionVariable(loop, (ValuePhiNode) phi, phi.valueAt(forwardEnd), stride, (BinaryArithmeticNode<?>) backValue);
ivs.put(phi, biv);
scanQueue.add(biv);
}
}
while (!scanQueue.isEmpty()) {
InductionVariable baseIv = scanQueue.remove();
ValueNode baseIvNode = baseIv.valueNode();
for (ValueNode op : baseIvNode.usages().filter(ValueNode.class)) {
if (loop.isOutsideLoop(op)) {
continue;
}
if (op.usages().count() == 1 && op.usages().first() == baseIvNode) {
/*
* This is just the base induction variable increment with no other uses so
* don't bother reporting it.
*/
continue;
}
InductionVariable iv = null;
ValueNode offset = addSub(loop, op, baseIvNode);
ValueNode scale;
if (offset != null) {
iv = new DerivedOffsetInductionVariable(loop, baseIv, offset, (BinaryArithmeticNode<?>) op);
} else if (op instanceof NegateNode) {
iv = new DerivedScaledInductionVariable(loop, baseIv, (NegateNode) op);
} else if ((scale = mul(loop, op, baseIvNode)) != null) {
iv = new DerivedScaledInductionVariable(loop, baseIv, scale, op);
} else {
boolean isValidConvert = op instanceof PiNode || op instanceof SignExtendNode;
if (!isValidConvert && op instanceof ZeroExtendNode) {
ZeroExtendNode zeroExtendNode = (ZeroExtendNode) op;
isValidConvert = zeroExtendNode.isInputAlwaysPositive() || ((IntegerStamp) zeroExtendNode.stamp(NodeView.DEFAULT)).isPositive();
}
if (isValidConvert) {
iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(NodeView.DEFAULT), op);
}
}
if (iv != null) {
ivs.put(op, iv);
scanQueue.offer(iv);
}
}
}
return ivs;
}
use of org.graalvm.compiler.nodes.PiNode in project graal by oracle.
the class BytecodeParser method createExceptionDispatch.
private void createExceptionDispatch(ExceptionDispatchBlock block) {
lastInstr = finishInstruction(lastInstr, frameState);
assert frameState.stackSize() == 1 : frameState;
if (block.handler.isCatchAll()) {
assert block.getSuccessorCount() == 1;
appendGoto(block.getSuccessor(0));
return;
}
JavaType catchType = block.handler.getCatchType();
if (graphBuilderConfig.eagerResolving()) {
catchType = lookupType(block.handler.catchTypeCPI(), INSTANCEOF);
}
if (catchType instanceof ResolvedJavaType) {
TypeReference checkedCatchType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) catchType);
if (graphBuilderConfig.getSkippedExceptionTypes() != null) {
for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
if (skippedType.isAssignableFrom(checkedCatchType.getType())) {
BciBlock nextBlock = block.getSuccessorCount() == 1 ? blockMap.getUnwindBlock() : block.getSuccessor(1);
ValueNode exception = frameState.stack[0];
FixedNode trueSuccessor = graph.add(new DeoptimizeNode(InvalidateReprofile, UnreachedCode));
FixedNode nextDispatch = createTarget(nextBlock, frameState);
append(new IfNode(graph.addOrUniqueWithInputs(createInstanceOf(checkedCatchType, exception)), trueSuccessor, nextDispatch, 0));
return;
}
}
}
BciBlock nextBlock = block.getSuccessorCount() == 1 ? blockMap.getUnwindBlock() : block.getSuccessor(1);
ValueNode exception = frameState.stack[0];
/* Anchor for the piNode, which must be before any LoopExit inserted by createTarget. */
BeginNode piNodeAnchor = graph.add(new BeginNode());
ObjectStamp checkedStamp = StampFactory.objectNonNull(checkedCatchType);
PiNode piNode = graph.addWithoutUnique(new PiNode(exception, checkedStamp));
frameState.pop(JavaKind.Object);
frameState.push(JavaKind.Object, piNode);
FixedNode catchSuccessor = createTarget(block.getSuccessor(0), frameState);
frameState.pop(JavaKind.Object);
frameState.push(JavaKind.Object, exception);
FixedNode nextDispatch = createTarget(nextBlock, frameState);
piNodeAnchor.setNext(catchSuccessor);
IfNode ifNode = append(new IfNode(graph.unique(createInstanceOf(checkedCatchType, exception)), piNodeAnchor, nextDispatch, 0.5));
assert ifNode.trueSuccessor() == piNodeAnchor;
piNode.setGuard(ifNode.trueSuccessor());
} else {
handleUnresolvedExceptionType(catchType);
}
}
use of org.graalvm.compiler.nodes.PiNode in project graal by oracle.
the class GraphUtil method skipPi.
public static ValueNode skipPi(ValueNode node) {
ValueNode n = node;
while (n instanceof PiNode) {
PiNode piNode = (PiNode) n;
n = piNode.getOriginalNode();
}
return n;
}
Aggregations