< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java
Print this page
rev 56282 : [mq]: graal
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
@@ -36,20 +36,22 @@
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.LOAD_COUNTERS;
import static org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction.RESOLVE;
import static org.graalvm.compiler.lir.LIRValueUtil.asConstant;
import static org.graalvm.compiler.lir.LIRValueUtil.isConstantValue;
+import java.util.EnumSet;
import java.util.function.Function;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler.PrefetchMode;
import org.graalvm.compiler.core.aarch64.AArch64ArithmeticLIRGenerator;
import org.graalvm.compiler.core.aarch64.AArch64LIRGenerator;
import org.graalvm.compiler.core.aarch64.AArch64LIRKindTool;
import org.graalvm.compiler.core.common.CompressEncoding;
+import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.core.common.spi.LIRKindTool;
@@ -66,11 +68,11 @@
import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
import org.graalvm.compiler.hotspot.stubs.Stub;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LabelRef;
-import org.graalvm.compiler.lir.StandardOp.SaveRegistersOp;
+import org.graalvm.compiler.lir.StandardOp.ZapRegistersOp;
import org.graalvm.compiler.lir.SwitchStrategy;
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.VirtualStackSlot;
import org.graalvm.compiler.lir.aarch64.AArch64AddressValue;
import org.graalvm.compiler.lir.aarch64.AArch64CCall;
@@ -80,10 +82,11 @@
import org.graalvm.compiler.lir.aarch64.AArch64Move;
import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp;
import org.graalvm.compiler.lir.aarch64.AArch64PrefetchOp;
import org.graalvm.compiler.lir.aarch64.AArch64RestoreRegistersOp;
import org.graalvm.compiler.lir.aarch64.AArch64SaveRegistersOp;
+import org.graalvm.compiler.lir.aarch64.AArch64ZeroMemoryOp;
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.aarch64.AArch64Kind;
@@ -165,14 +168,13 @@
}
/**
* @param savedRegisters the registers saved by this operation which may be subject to pruning
* @param savedRegisterLocations the slots to which the registers are saved
- * @param supportsRemove determines if registers can be pruned
*/
- protected AArch64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations, boolean supportsRemove) {
- AArch64SaveRegistersOp save = new AArch64SaveRegistersOp(savedRegisters, savedRegisterLocations, supportsRemove);
+ protected AArch64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations) {
+ AArch64SaveRegistersOp save = new AArch64SaveRegistersOp(savedRegisters, savedRegisterLocations);
append(save);
return save;
}
/**
@@ -180,27 +182,26 @@
*/
protected VirtualStackSlot allocateSaveRegisterLocation(Register register) {
PlatformKind kind = target().arch.getLargestStorableKind(register.getRegisterCategory());
if (kind.getVectorLength() > 1) {
// we don't use vector registers, so there is no need to save them
- kind = AArch64Kind.QWORD;
+ kind = AArch64Kind.DOUBLE;
}
return getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind));
}
/**
* Adds a node to the graph that saves all allocatable registers to the stack.
*
- * @param supportsRemove determines if registers can be pruned
* @return the register save node
*/
- private AArch64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters, boolean supportsRemove) {
+ private AArch64SaveRegistersOp emitSaveAllRegisters(Register[] savedRegisters) {
AllocatableValue[] savedRegisterLocations = new AllocatableValue[savedRegisters.length];
for (int i = 0; i < savedRegisters.length; i++) {
savedRegisterLocations[i] = allocateSaveRegisterLocation(savedRegisters[i]);
}
- return emitSaveRegisters(savedRegisters, savedRegisterLocations, supportsRemove);
+ return emitSaveRegisters(savedRegisters, savedRegisterLocations);
}
protected void emitRestoreRegisters(AArch64SaveRegistersOp save) {
append(new AArch64RestoreRegistersOp(save.getSlots().clone(), save));
}
@@ -345,15 +346,13 @@
HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage;
boolean destroysRegisters = hotspotLinkage.destroysRegisters();
AArch64SaveRegistersOp save = null;
Stub stub = getStub();
- if (destroysRegisters) {
- if (stub != null && stub.preservesRegisters()) {
+ if (destroysRegisters && stub != null && stub.shouldSaveRegistersAroundCalls()) {
Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray();
- save = emitSaveAllRegisters(savedRegisters, true);
- }
+ save = emitSaveAllRegisters(savedRegisters);
}
Variable result;
LIRFrameState debugInfo = null;
if (hotspotLinkage.needsDebugInfo()) {
@@ -377,24 +376,20 @@
label = null;
} else {
result = super.emitForeignCall(hotspotLinkage, debugInfo, args);
}
- if (destroysRegisters) {
- if (stub != null) {
- if (stub.preservesRegisters()) {
+ if (save != null) {
HotSpotLIRGenerationResult generationResult = getResult();
LIRFrameState key = currentRuntimeCallInfo;
if (key == null) {
key = LIRFrameState.NO_STATE;
}
assert !generationResult.getCalleeSaveInfo().containsKey(key);
generationResult.getCalleeSaveInfo().put(key, save);
emitRestoreRegisters(save);
}
- }
- }
return result;
}
@Override
@@ -537,14 +532,38 @@
public void setDebugInfoBuilder(HotSpotDebugInfoBuilder debugInfoBuilder) {
this.debugInfoBuilder = debugInfoBuilder;
}
@Override
- public SaveRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) {
+ public ZapRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) {
throw GraalError.unimplemented();
}
@Override
public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) {
throw GraalError.unimplemented();
}
+
+ @Override
+ public void emitZeroMemory(Value address, Value length) {
+ int dczidValue = config.psrInfoDczidValue;
+ EnumSet<AArch64.Flag> flags = ((AArch64) target().arch).getFlags();
+
+ // ARMv8-A architecture reference manual D12.2.35 Data Cache Zero ID register says:
+ // * BS, bits [3:0] indicate log2 of the DC ZVA block size in (4-byte) words.
+ // * DZP, bit [4] of indicates whether use of DC ZVA instruction is prohibited.
+ int zvaLength = 4 << (dczidValue & 0xF);
+ boolean isDcZvaProhibited = ((dczidValue & 0x10) != 0);
+
+ // Use DC ZVA if it's not prohibited and AArch64 HotSpot flag UseBlockZeroing is on.
+ boolean useDcZva = !isDcZvaProhibited && flags.contains(AArch64.Flag.UseBlockZeroing);
+
+ // Set zva length negative (unknown at compile-time) for AOT compilation, since the value
+ // could be different on different AArch64 CPU implementations.
+ if (GraalOptions.ImmutableCode.getValue(getResult().getLIR().getOptions())) {
+ useDcZva = false;
+ }
+
+ // Value address is 8-byte aligned; Value length is multiple of 8.
+ append(new AArch64ZeroMemoryOp(asAllocatable(address), asAllocatable(length), useDcZva, zvaLength));
+ }
}
< prev index next >