use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class UnsafeAutomaticSubstitutionProcessor method processArrayIndexShift.
/**
* Try to compute the arrayIndexShift. Return true if successful, false otherwise.
*/
private boolean processArrayIndexShift(ResolvedJavaType type, Class<?> arrayClass, ValueNode indexScaleValue, boolean silentFailure) {
NodeIterable<MethodCallTargetNode> loadMethodCallTargetUsages = indexScaleValue.usages().filter(MethodCallTargetNode.class);
for (MethodCallTargetNode methodCallTarget : loadMethodCallTargetUsages) {
/* Iterate over all the calls that use the index scale value. */
if (isInvokeTo(methodCallTarget.invoke(), integerNumberOfLeadingZerosMethod)) {
/*
* Found a call to Integer.numberOfLeadingZeros(int) that uses the array index scale
* field. Check if it is used to calculate the array index shift, i.e., log2 of the
* array index scale.
*/
ResolvedJavaField indexShiftField = null;
List<String> unsuccessfulReasons = new ArrayList<>();
Invoke numberOfLeadingZerosInvoke = methodCallTarget.invoke();
NodeIterable<SubNode> numberOfLeadingZerosInvokeSubUsages = numberOfLeadingZerosInvoke.asNode().usages().filter(SubNode.class);
if (numberOfLeadingZerosInvokeSubUsages.count() == 1) {
/*
* Found the SubNode. Determine if it computes the array index shift. If so find
* the field where the value is stored.
*/
SubNode subNode = numberOfLeadingZerosInvokeSubUsages.first();
if (subNodeComputesLog2(subNode, numberOfLeadingZerosInvoke)) {
indexShiftField = extractValueStoreField(subNode, unsuccessfulReasons);
} else {
unsuccessfulReasons.add("The index array scale value provided by " + indexScaleValue + " is not used to calculate the array index shift.");
}
} else {
unsuccessfulReasons.add("The call to " + methodCallTarget.targetMethod().format("%H.%n(%p)") + " has multiple uses.");
}
if (indexShiftField != null) {
ResolvedJavaField finalIndexShiftField = indexShiftField;
Supplier<ComputedValueField> supplier = () -> new ComputedValueField(finalIndexShiftField, null, Kind.ArrayIndexShift, arrayClass, null, true);
if (tryAutomaticRecomputation(indexShiftField, Kind.ArrayIndexShift, supplier)) {
reportSuccessfulAutomaticRecomputation(Kind.ArrayIndexShift, indexShiftField, arrayClass.getCanonicalName());
return true;
}
} else {
if (!silentFailure) {
reportUnsuccessfulAutomaticRecomputation(type, numberOfLeadingZerosInvoke, Kind.ArrayIndexShift, unsuccessfulReasons);
}
}
}
}
return false;
}
use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class GraphKit method createInvoke.
/**
* Creates and appends an {@link InvokeNode} for a call to a given method with a given set of
* arguments.
*/
@SuppressWarnings("try")
public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.substitution(graph.currentNodeSourcePosition(), method))) {
assert method.isStatic() == (invokeKind == InvokeKind.Static);
Signature signature = method.getSignature();
JavaType returnType = signature.getReturnType(null);
assert checkArgs(method, args);
StampPair returnStamp = graphBuilderPlugins.getOverridingStamp(this, returnType, false);
if (returnStamp == null) {
returnStamp = StampFactory.forDeclaredType(graph.getAssumptions(), returnType, false);
}
MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, bci));
InvokeNode invoke = append(new InvokeNode(callTarget, bci));
if (frameStateBuilder != null) {
if (invoke.getStackKind() != JavaKind.Void) {
frameStateBuilder.push(invoke.getStackKind(), invoke);
}
invoke.setStateAfter(frameStateBuilder.create(bci, invoke));
if (invoke.getStackKind() != JavaKind.Void) {
frameStateBuilder.pop(invoke.getStackKind());
}
}
return invoke;
}
}
use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class PEGraphDecoder method handleInvoke.
@Override
protected LoopScope handleInvoke(MethodScope s, LoopScope loopScope, InvokeData invokeData) {
PEMethodScope methodScope = (PEMethodScope) s;
/*
* Decode the call target, but do not add it to the graph yet. This avoids adding usages for
* all the arguments, which are expensive to remove again when we can inline the method.
*/
assert invokeData.invoke.callTarget() == null : "callTarget edge is ignored during decoding of Invoke";
CallTargetNode callTarget = (CallTargetNode) decodeFloatingNode(methodScope, loopScope, invokeData.callTargetOrderId);
if (callTarget instanceof MethodCallTargetNode) {
MethodCallTargetNode methodCall = (MethodCallTargetNode) callTarget;
if (methodCall.invokeKind().hasReceiver()) {
invokeData.constantReceiver = methodCall.arguments().get(0).asJavaConstant();
NodeSourcePosition invokePosition = invokeData.invoke.asNode().getNodeSourcePosition();
if (invokeData.constantReceiver != null && invokePosition != null) {
// new NodeSourcePosition(invokeData.constantReceiver,
// invokePosition.getCaller(), invokePosition.getMethod(),
// invokePosition.getBCI());
}
}
LoopScope inlineLoopScope = trySimplifyInvoke(methodScope, loopScope, invokeData, (MethodCallTargetNode) callTarget);
if (inlineLoopScope != null) {
return inlineLoopScope;
}
}
/* We know that we need an invoke, so now we can add the call target to the graph. */
graph.add(callTarget);
registerNode(loopScope, invokeData.callTargetOrderId, callTarget, false, false);
return super.handleInvoke(methodScope, loopScope, invokeData);
}
use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class MacroNode method createInvoke.
protected InvokeNode createInvoke() {
MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(invokeKind, targetMethod, arguments.toArray(new ValueNode[arguments.size()]), returnStamp, null));
InvokeNode invoke = graph().add(new InvokeNode(callTarget, bci));
if (stateAfter() != null) {
invoke.setStateAfter(stateAfter().duplicate());
if (getStackKind() != JavaKind.Void) {
invoke.stateAfter().replaceFirstInput(this, invoke);
}
}
return invoke;
}
use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class PartialEvaluator method postPartialEvaluation.
private static void postPartialEvaluation(final StructuredGraph graph) {
NeverPartOfCompilationNode.verifyNotFoundIn(graph);
for (AllowMaterializeNode materializeNode : graph.getNodes(AllowMaterializeNode.TYPE).snapshot()) {
materializeNode.replaceAtUsages(materializeNode.getFrame());
graph.removeFixed(materializeNode);
}
TruffleCompilerRuntime rt = TruffleCompilerRuntime.getRuntime();
for (VirtualObjectNode virtualObjectNode : graph.getNodes(VirtualObjectNode.TYPE)) {
if (virtualObjectNode instanceof VirtualInstanceNode) {
VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode;
ResolvedJavaType type = virtualInstanceNode.type();
if (rt.isValueType(type)) {
virtualInstanceNode.setIdentity(false);
}
}
}
if (!TruffleCompilerOptions.getValue(TruffleInlineAcrossTruffleBoundary)) {
// Do not inline across Truffle boundaries.
for (MethodCallTargetNode mct : graph.getNodes(MethodCallTargetNode.TYPE)) {
InlineInfo inlineInfo = rt.getInlineInfo(mct.targetMethod(), false);
if (!inlineInfo.allowsInlining()) {
mct.invoke().setUseForInlining(false);
}
}
}
}
Aggregations