Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,4 @@ protected boolean peephole(ValueNode valueNode) {
public AArch64LIRGenerator getLIRGeneratorTool() {
return (AArch64LIRGenerator) super.getLIRGeneratorTool();
}

@Override
protected void emitPrologue(StructuredGraph graph) {
// XXX Maybe we need something like this.
// getLIRGeneratorTool().emitLoadConstantTableBase();
super.emitPrologue(graph);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,15 @@ protected void emitPrologue(StructuredGraph graph) {
CallingConvention incomingArguments = gen.getResult().getCallingConvention();

Value[] params = new Value[incomingArguments.getArgumentCount()];
for (int i = 0; i < params.length; i++) {
prologAssignParams(incomingArguments, params);

gen.emitIncomingValues(params);

prologSetParameterNodes(graph, params);
}

protected final void prologAssignParams(CallingConvention incomingArguments, Value[] params) {
for (int i = 0; i < incomingArguments.getArgumentCount(); i++) {
params[i] = incomingArguments.getArgument(i);
if (ValueUtil.isStackSlot(params[i])) {
StackSlot slot = ValueUtil.asStackSlot(params[i]);
Expand All @@ -525,9 +533,9 @@ protected void emitPrologue(StructuredGraph graph) {
}
}
}
}

gen.emitIncomingValues(params);

protected void prologSetParameterNodes(StructuredGraph graph, Value[] params) {
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value paramValue = params[param.index()];
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue + " " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
package org.graalvm.compiler.hotspot.aarch64;

import static jdk.vm.ci.aarch64.AArch64.lr;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.inlineCacheRegister;
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.metaspaceMethodRegister;
Expand All @@ -52,7 +51,6 @@
import org.graalvm.compiler.nodes.FullInfopointNode;
import org.graalvm.compiler.nodes.IndirectCallTargetNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.SafepointNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
Expand All @@ -63,8 +61,6 @@
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.ValueUtil;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.AllocatableValue;
Expand Down Expand Up @@ -97,25 +93,14 @@ private AArch64HotSpotLIRGenerator getGen() {
protected void emitPrologue(StructuredGraph graph) {
CallingConvention incomingArguments = gen.getResult().getCallingConvention();
Value[] params = new Value[incomingArguments.getArgumentCount() + 2];
for (int i = 0; i < incomingArguments.getArgumentCount(); i++) {
params[i] = incomingArguments.getArgument(i);
if (isStackSlot(params[i])) {
StackSlot slot = ValueUtil.asStackSlot(params[i]);
if (slot.isInCallerFrame() && !gen.getResult().getLIR().hasArgInCallerFrame()) {
gen.getResult().getLIR().setHasArgInCallerFrame();
}
}
}

prologAssignParams(incomingArguments, params);
params[params.length - 2] = fp.asValue(LIRKind.value(AArch64Kind.QWORD));
params[params.length - 1] = lr.asValue(LIRKind.value(AArch64Kind.QWORD));

gen.emitIncomingValues(params);

for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value paramValue = params[param.index()];
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue.getValueKind() + " != " + param.stamp(NodeView.DEFAULT);
setResult(param, gen.emitMove(paramValue));
}
prologSetParameterNodes(graph, params);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
package org.graalvm.compiler.hotspot.amd64;

import static jdk.vm.ci.amd64.AMD64.rbp;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import static org.graalvm.compiler.hotspot.HotSpotBackend.EXCEPTION_HANDLER_IN_CALLER;

import org.graalvm.compiler.core.amd64.AMD64NodeLIRBuilder;
Expand All @@ -50,7 +49,6 @@
import org.graalvm.compiler.nodes.FullInfopointNode;
import org.graalvm.compiler.nodes.IndirectCallTargetNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.SafepointNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
Expand All @@ -71,8 +69,6 @@
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.ValueUtil;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.AllocatableValue;
Expand Down Expand Up @@ -103,19 +99,10 @@ protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeVal

@Override
protected void emitPrologue(StructuredGraph graph) {

CallingConvention incomingArguments = gen.getResult().getCallingConvention();

Value[] params = new Value[incomingArguments.getArgumentCount() + 1];
for (int i = 0; i < params.length - 1; i++) {
params[i] = incomingArguments.getArgument(i);
if (isStackSlot(params[i])) {
StackSlot slot = ValueUtil.asStackSlot(params[i]);
if (slot.isInCallerFrame() && !gen.getResult().getLIR().hasArgInCallerFrame()) {
gen.getResult().getLIR().setHasArgInCallerFrame();
}
}
}

prologAssignParams(incomingArguments, params);
params[params.length - 1] = rbp.asValue(LIRKind.value(AMD64Kind.QWORD));

gen.emitIncomingValues(params);
Expand All @@ -124,12 +111,7 @@ protected void emitPrologue(StructuredGraph graph) {

getGen().append(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack());

for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value paramValue = params[param.index()];
assert paramValue.getValueKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT))) : paramValue.getValueKind() + " != " +
getLIRGeneratorTool().getLIRKind(param.stamp(NodeView.DEFAULT)) + " for " + param.stamp(NodeView.DEFAULT);
setResult(param, gen.emitMove(paramValue));
}
prologSetParameterNodes(graph, params);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.SafepointNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.spi.CoreProviders;
Expand All @@ -120,7 +121,9 @@
import com.oracle.svm.core.deopt.Deoptimizer;
import com.oracle.svm.core.graal.code.PatchConsumerFactory;
import com.oracle.svm.core.graal.code.SubstrateBackend;
import com.oracle.svm.core.graal.code.SubstrateCallingConvention;
import com.oracle.svm.core.graal.code.SubstrateCallingConventionKind;
import com.oracle.svm.core.graal.code.SubstrateCallingConventionType;
import com.oracle.svm.core.graal.code.SubstrateCompiledCode;
import com.oracle.svm.core.graal.code.SubstrateDataBuilder;
import com.oracle.svm.core.graal.code.SubstrateDebugInfoBuilder;
Expand Down Expand Up @@ -530,6 +533,35 @@ private boolean getDestroysCallerSavedRegisters(ResolvedJavaMethod targetMethod)
return ((SubstrateAArch64LIRGenerator) gen).getDestroysCallerSavedRegisters(targetMethod);
}

@Override
protected void prologSetParameterNodes(StructuredGraph graph, Value[] params) {
SubstrateCallingConvention convention = (SubstrateCallingConvention) gen.getResult().getCallingConvention();
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value inputValue = params[param.index()];
Value paramValue = gen.emitMove(inputValue);

/*
* In the native ABI some parameters are not extended to the equivalent Java stack
* kinds.
*/
if (inputValue.getPlatformKind().getSizeInBytes() < Integer.BYTES) {
SubstrateCallingConventionType type = (SubstrateCallingConventionType) convention.getType();
assert !type.outgoing && type.nativeABI();
JavaKind kind = convention.getArgumentStorageKinds()[param.index()];
JavaKind stackKind = kind.getStackKind();
if (kind.isUnsigned()) {
paramValue = gen.getArithmetic().emitZeroExtend(paramValue, kind.getBitCount(), stackKind.getBitCount());
} else {
paramValue = gen.getArithmetic().emitSignExtend(paramValue, kind.getBitCount(), stackKind.getBitCount());
}
}

assert paramValue.getValueKind().equals(gen.getLIRKind(param.stamp(NodeView.DEFAULT)));

setResult(param, paramValue);
}
}

/**
* For invokes that have an exception handler, the register used for the incoming exception
* is destroyed at the call site even when registers are caller saved. The normal object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import java.util.ArrayList;

import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.nativeimage.Platform;

import com.oracle.svm.core.OS;
import com.oracle.svm.core.ReservedRegisters;
Expand Down Expand Up @@ -242,21 +243,31 @@ private int javaStackParameterAssignment(ValueKindFactory<?> valueKindFactory, A
}

/**
* The Darwin calling convention expects arguments to be aligned to the argument kind.
* The Linux calling convention expects stack arguments to be aligned to at least 8 bytes, but
* any unused padding bits have unspecified values.
*
* For more details, see <a
* href=https://github.com/ARM-software/abi-aa/blob/d6e9abbc5e9cdcaa0467d8187eec0049b44044c4/aapcs64/aapcs64.rst#parameter-passing-rules>the
* AArch64 procedure call standard</a>.
*/
private int linuxNativeStackParameterAssignment(ValueKindFactory<?> valueKindFactory, AllocatableValue[] locations, int index, JavaKind kind, int currentStackOffset, boolean isOutgoing) {
ValueKind<?> valueKind = valueKindFactory.getValueKind(isOutgoing ? kind.getStackKind() : kind);
int alignment = Math.max(kind.getByteCount(), target.wordSize);
locations[index] = StackSlot.get(valueKind, currentStackOffset, !isOutgoing);
return currentStackOffset + alignment;
}

/**
* The Darwin calling convention expects stack arguments to be aligned to the argument kind.
*
* For more details, see <a
* href=https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms>https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms</a>.
*/
private int darwinNativeStackParameterAssignment(ValueKindFactory<?> valueKindFactory, AllocatableValue[] locations, int index, JavaKind kind, int currentStackOffset, boolean isOutgoing) {
if (isOutgoing) {
int paramByteSize = kind.getByteCount();
int alignedStackOffset = NumUtil.roundUp(currentStackOffset, paramByteSize);
locations[index] = StackSlot.get(valueKindFactory.getValueKind(kind), alignedStackOffset, false);
return alignedStackOffset + paramByteSize;
} else {
/* Native-to-Java calls follow the normal Java convention. */
return javaStackParameterAssignment(valueKindFactory, locations, index, kind, currentStackOffset, isOutgoing);
}
private static int darwinNativeStackParameterAssignment(ValueKindFactory<?> valueKindFactory, AllocatableValue[] locations, int index, JavaKind kind, int currentStackOffset, boolean isOutgoing) {
int paramByteSize = kind.getByteCount();
int alignedStackOffset = NumUtil.roundUp(currentStackOffset, paramByteSize);
locations[index] = StackSlot.get(valueKindFactory.getValueKind(kind), alignedStackOffset, !isOutgoing);
return alignedStackOffset + paramByteSize;
}

@Override
Expand Down Expand Up @@ -309,10 +320,28 @@ public CallingConvention getCallingConvention(Type t, JavaType returnType, JavaT

}
if (register != null) {
locations[i] = register.asValue(valueKindFactory.getValueKind(kind.getStackKind()));
/*
* The AArch64 procedure call standard does not require subword (i.e., boolean,
* byte, char, short) values to be extended to 32 bits. Hence, for incoming native
* calls, we can only assume the bits sizes as specified in the standard.
*
* Since within the graal compiler subwords are already extended to 32 bits, we save
* extended values in outgoing calls.
*
* Darwin deviates from the call standard and requires the caller to extend subword
* values.
*/
boolean useJavaKind = isEntryPoint && (Platform.includedIn(Platform.LINUX.class) || Platform.includedIn(Platform.WINDOWS.class));
locations[i] = register.asValue(valueKindFactory.getValueKind(useJavaKind ? kind : kind.getStackKind()));
} else {
if (type.nativeABI() && OS.DARWIN.isCurrent()) {
currentStackOffset = darwinNativeStackParameterAssignment(valueKindFactory, locations, i, kind, currentStackOffset, type.outgoing);
if (type.nativeABI()) {
if (Platform.includedIn(Platform.LINUX.class)) {
currentStackOffset = linuxNativeStackParameterAssignment(valueKindFactory, locations, i, kind, currentStackOffset, type.outgoing);
} else if (Platform.includedIn(Platform.DARWIN.class)) {
currentStackOffset = darwinNativeStackParameterAssignment(valueKindFactory, locations, i, kind, currentStackOffset, type.outgoing);
} else {
throw VMError.shouldNotReachHere();
}
} else {
currentStackOffset = javaStackParameterAssignment(valueKindFactory, locations, i, kind, currentStackOffset, type.outgoing);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
import org.graalvm.compiler.nodes.LogicNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.SafepointNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
Expand Down Expand Up @@ -616,6 +617,35 @@ protected DebugInfoBuilder createDebugInfoBuilder(StructuredGraph graph, NodeVal
return new SubstrateDebugInfoBuilder(graph, gen.getProviders().getMetaAccessExtensionProvider(), nodeValueMap);
}

@Override
protected void prologSetParameterNodes(StructuredGraph graph, Value[] params) {
SubstrateCallingConvention convention = (SubstrateCallingConvention) gen.getResult().getCallingConvention();
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
Value inputValue = params[param.index()];
Value paramValue = gen.emitMove(inputValue);

/*
* In the native ABI, some parameters are not extended to the equivalent Java stack
* kinds.
*/
if (inputValue.getPlatformKind().getSizeInBytes() < Integer.BYTES) {
SubstrateCallingConventionType type = (SubstrateCallingConventionType) convention.getType();
assert !type.outgoing && type.nativeABI();
JavaKind kind = convention.getArgumentStorageKinds()[param.index()];
JavaKind stackKind = kind.getStackKind();
if (kind.isUnsigned()) {
paramValue = gen.getArithmetic().emitZeroExtend(paramValue, kind.getBitCount(), stackKind.getBitCount());
} else {
paramValue = gen.getArithmetic().emitSignExtend(paramValue, kind.getBitCount(), stackKind.getBitCount());
}
}

assert paramValue.getValueKind().equals(gen.getLIRKind(param.stamp(NodeView.DEFAULT)));

setResult(param, paramValue);
}
}

@Override
public Value[] visitInvokeArguments(CallingConvention invokeCc, Collection<ValueNode> arguments) {
Value[] values = super.visitInvokeArguments(invokeCc, arguments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,21 @@ public CallingConvention getCallingConvention(Type t, JavaType returnType, JavaT
}
}

/*
* The AMD64 ABI does not specify whether subword (i.e., boolean, byte, char, short)
* values should be extended to 32 bits. Hence, for incoming native calls, we can only
* assume the bits sizes as specified in the standard.
*
* Since within the graal compiler subwords are already extended to 32 bits, we save
* extended values in outgoing calls. Note that some compilers also expect arguments to
* be extended (https://reviews.llvm.org/rG1db979bae832563efde2523bb36ddabad43293d8).
*/
ValueKind<?> paramValueKind = valueKindFactory.getValueKind(isEntryPoint ? kind : kind.getStackKind());
if (register != null) {
locations[i] = register.asValue(valueKindFactory.getValueKind(kind.getStackKind()));
locations[i] = register.asValue(paramValueKind);
} else {
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind.getStackKind());
locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.outgoing);
currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
locations[i] = StackSlot.get(paramValueKind, currentStackOffset, !type.outgoing);
currentStackOffset += Math.max(paramValueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
}
}

Expand Down