use of org.graalvm.compiler.nodes.StructuredGraph in project graal by oracle.
the class ObjectCloneNode method getLoweredSnippetGraph.
@Override
@SuppressWarnings("try")
protected StructuredGraph getLoweredSnippetGraph(LoweringTool tool) {
ResolvedJavaType type = StampTool.typeOrNull(getObject());
if (type != null) {
if (type.isArray()) {
Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getJavaKind());
if (method != null) {
final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method);
final Replacements replacements = tool.getReplacements();
StructuredGraph snippetGraph = null;
DebugContext debug = getDebug();
try (DebugContext.Scope s = debug.scope("ArrayCloneSnippet", snippetMethod)) {
snippetGraph = replacements.getSnippet(snippetMethod, null, graph().trackNodeSourcePosition(), this.getNodeSourcePosition());
} catch (Throwable e) {
throw debug.handle(e);
}
assert snippetGraph != null : "ObjectCloneSnippets should be installed";
assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
return lowerReplacement((StructuredGraph) snippetGraph.copy(getDebug()), tool);
}
assert false : "unhandled array type " + type.getComponentType().getJavaKind();
} else {
Assumptions assumptions = graph().getAssumptions();
type = getConcreteType(getObject().stamp(NodeView.DEFAULT));
if (type != null) {
StructuredGraph newGraph = new StructuredGraph.Builder(graph().getOptions(), graph().getDebug(), AllowAssumptions.ifNonNull(assumptions)).build();
ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp(NodeView.DEFAULT))));
NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
newGraph.addAfterFixed(newGraph.start(), newInstance);
ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance));
newGraph.addAfterFixed(newInstance, returnNode);
for (ResolvedJavaField field : type.getInstanceFields(true)) {
LoadFieldNode load = newGraph.add(LoadFieldNode.create(newGraph.getAssumptions(), param, field));
newGraph.addBeforeFixed(returnNode, load);
newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load)));
}
assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
return lowerReplacement(newGraph, tool);
}
}
}
assert getConcreteType(stamp(NodeView.DEFAULT)) == null;
return null;
}
use of org.graalvm.compiler.nodes.StructuredGraph in project graal by oracle.
the class ArrayCopyCallNode method lower.
@Override
public void lower(LoweringTool tool) {
if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
updateAlignedDisjoint();
ForeignCallDescriptor desc = HotSpotHostForeignCallsProvider.lookupArraycopyDescriptor(elementKind, isAligned(), isDisjoint(), isUninitialized(), locationIdentity.equals(LocationIdentity.any()));
StructuredGraph graph = graph();
ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
ValueNode len = getLength();
if (len.stamp(NodeView.DEFAULT).getStackKind() != JavaKind.Long) {
len = IntegerConvertNode.convert(len, StampFactory.forKind(JavaKind.Long), graph(), NodeView.DEFAULT);
}
ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len));
call.setStateAfter(stateAfter());
graph.replaceFixedWithFixed(this, call);
}
}
use of org.graalvm.compiler.nodes.StructuredGraph in project graal by oracle.
the class CheckcastArrayCopyCallNode method lower.
@Override
public void lower(LoweringTool tool) {
if (graph().getGuardsStage().areFrameStatesAtDeopts()) {
ForeignCallDescriptor desc = HotSpotHostForeignCallsProvider.lookupCheckcastArraycopyDescriptor(isUninit());
StructuredGraph graph = graph();
ValueNode srcAddr = computeBase(getSource(), getSourcePosition());
ValueNode destAddr = computeBase(getDestination(), getDestinationPosition());
ValueNode len = getLength();
if (len.stamp(NodeView.DEFAULT).getStackKind() != runtime.getTarget().wordJavaKind) {
len = IntegerConvertNode.convert(len, StampFactory.forKind(runtime.getTarget().wordJavaKind), graph(), NodeView.DEFAULT);
}
ForeignCallNode call = graph.add(new ForeignCallNode(runtime.getHostBackend().getForeignCalls(), desc, srcAddr, destAddr, len, superCheckOffset, destElemKlass));
call.setStateAfter(stateAfter());
graph.replaceFixedWithFixed(this, call);
}
}
use of org.graalvm.compiler.nodes.StructuredGraph in project graal by oracle.
the class ForeignCallStub method getGraph.
/**
* Creates a graph for this stub.
* <p>
* If the stub returns an object, the graph created corresponds to this pseudo code:
*
* <pre>
* Object foreignFunctionStub(args...) {
* foreignFunction(currentThread, args);
* if (clearPendingException(thread())) {
* getAndClearObjectResult(thread());
* DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
* }
* return verifyObject(getAndClearObjectResult(thread()));
* }
* </pre>
*
* If the stub returns a primitive or word, the graph created corresponds to this pseudo code
* (using {@code int} as the primitive return type):
*
* <pre>
* int foreignFunctionStub(args...) {
* int result = foreignFunction(currentThread, args);
* if (clearPendingException(thread())) {
* DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
* }
* return result;
* }
* </pre>
*
* If the stub is void, the graph created corresponds to this pseudo code:
*
* <pre>
* void foreignFunctionStub(args...) {
* foreignFunction(currentThread, args);
* if (clearPendingException(thread())) {
* DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint);
* }
* }
* </pre>
*
* In each example above, the {@code currentThread} argument is the C++ JavaThread value (i.e.,
* %r15 on AMD64) and is only prepended if {@link #prependThread} is true.
*/
@Override
@SuppressWarnings("try")
protected StructuredGraph getGraph(DebugContext debug, CompilationIdentifier compilationId) {
WordTypes wordTypes = providers.getWordTypes();
Class<?>[] args = linkage.getDescriptor().getArgumentTypes();
boolean isObjectResult = !LIRKind.isValue(linkage.getOutgoingCallingConvention().getReturn());
try {
ResolvedJavaMethod thisMethod = providers.getMetaAccess().lookupJavaMethod(ForeignCallStub.class.getDeclaredMethod("getGraph", DebugContext.class, CompilationIdentifier.class));
GraphKit kit = new GraphKit(debug, thisMethod, providers, wordTypes, providers.getGraphBuilderPlugins(), compilationId, toString());
StructuredGraph graph = kit.getGraph();
ParameterNode[] params = createParameters(kit, args);
ReadRegisterNode thread = kit.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), wordTypes.getWordKind(), true, false));
ValueNode result = createTargetCall(kit, params, thread);
kit.createInvoke(StubUtil.class, "handlePendingException", thread, ConstantNode.forBoolean(isObjectResult, graph));
if (isObjectResult) {
InvokeNode object = kit.createInvoke(HotSpotReplacementsUtil.class, "getAndClearObjectResult", thread);
result = kit.createInvoke(StubUtil.class, "verifyObject", object);
}
kit.append(new ReturnNode(linkage.getDescriptor().getResultType() == void.class ? null : result));
debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Initial stub graph");
kit.inlineInvokes();
new RemoveValueProxyPhase().apply(graph);
debug.dump(DebugContext.VERBOSE_LEVEL, graph, "Stub graph before compilation");
return graph;
} catch (Exception e) {
throw GraalError.shouldNotReachHere(e);
}
}
use of org.graalvm.compiler.nodes.StructuredGraph in project graal by oracle.
the class InliningUtil method nonNullReceiver.
/**
* Gets the receiver for an invoke, adding a guard if necessary to ensure it is non-null, and
* ensuring that the resulting type is compatible with the method being invoked.
*/
@SuppressWarnings("try")
public static ValueNode nonNullReceiver(Invoke invoke) {
try (DebugCloseable position = invoke.asNode().withNodeSourcePosition()) {
MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
assert !callTarget.isStatic() : callTarget.targetMethod();
StructuredGraph graph = callTarget.graph();
ValueNode oldReceiver = callTarget.arguments().get(0);
ValueNode newReceiver = oldReceiver;
if (newReceiver.getStackKind() == JavaKind.Object) {
if (invoke.getInvokeKind() == InvokeKind.Special) {
Stamp paramStamp = newReceiver.stamp(NodeView.DEFAULT);
Stamp stamp = paramStamp.join(StampFactory.object(TypeReference.create(graph.getAssumptions(), callTarget.targetMethod().getDeclaringClass())));
if (!stamp.equals(paramStamp)) {
// The verifier and previous optimizations guarantee unconditionally that
// the
// receiver is at least of the type of the method holder for a special
// invoke.
newReceiver = graph.unique(new PiNode(newReceiver, stamp));
}
}
if (!StampTool.isPointerNonNull(newReceiver)) {
LogicNode condition = graph.unique(IsNullNode.create(newReceiver));
FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, NullCheckException, InvalidateReprofile, true));
PiNode nonNullReceiver = graph.unique(new PiNode(newReceiver, StampFactory.objectNonNull(), fixedGuard));
graph.addBeforeFixed(invoke.asNode(), fixedGuard);
newReceiver = nonNullReceiver;
}
}
if (newReceiver != oldReceiver) {
callTarget.replaceFirstInput(oldReceiver, newReceiver);
}
return newReceiver;
}
}
Aggregations