< 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 **** /* ! * Copyright (c) 2015, 2018, 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 --- 1,7 ---- /* ! * 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,55 **** --- 36,57 ---- 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,76 **** 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.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; --- 68,78 ---- 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.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,89 **** --- 82,92 ---- 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,178 **** } /** * @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); append(save); return save; } /** --- 168,180 ---- } /** * @param savedRegisters the registers saved by this operation which may be subject to pruning * @param savedRegisterLocations the slots to which the registers are saved */ ! protected AArch64SaveRegistersOp emitSaveRegisters(Register[] savedRegisters, AllocatableValue[] savedRegisterLocations) { ! AArch64SaveRegistersOp save = new AArch64SaveRegistersOp(savedRegisters, savedRegisterLocations); append(save); return save; } /**
*** 180,206 **** */ 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; } 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) { AllocatableValue[] savedRegisterLocations = new AllocatableValue[savedRegisters.length]; for (int i = 0; i < savedRegisters.length; i++) { savedRegisterLocations[i] = allocateSaveRegisterLocation(savedRegisters[i]); } ! return emitSaveRegisters(savedRegisters, savedRegisterLocations, supportsRemove); } protected void emitRestoreRegisters(AArch64SaveRegistersOp save) { append(new AArch64RestoreRegistersOp(save.getSlots().clone(), save)); } --- 182,207 ---- */ 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.DOUBLE; } return getResult().getFrameMapBuilder().allocateSpillSlot(LIRKind.value(kind)); } /** * Adds a node to the graph that saves all allocatable registers to the stack. * * @return the register save node */ ! 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); } protected void emitRestoreRegisters(AArch64SaveRegistersOp save) { append(new AArch64RestoreRegistersOp(save.getSlots().clone(), save)); }
*** 345,359 **** HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage; boolean destroysRegisters = hotspotLinkage.destroysRegisters(); AArch64SaveRegistersOp save = null; Stub stub = getStub(); ! if (destroysRegisters) { ! if (stub != null && stub.preservesRegisters()) { Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray(); ! save = emitSaveAllRegisters(savedRegisters, true); ! } } Variable result; LIRFrameState debugInfo = null; if (hotspotLinkage.needsDebugInfo()) { --- 346,358 ---- HotSpotForeignCallLinkage hotspotLinkage = (HotSpotForeignCallLinkage) linkage; boolean destroysRegisters = hotspotLinkage.destroysRegisters(); AArch64SaveRegistersOp save = null; Stub stub = getStub(); ! if (destroysRegisters && stub != null && stub.shouldSaveRegistersAroundCalls()) { Register[] savedRegisters = getRegisterConfig().getAllocatableRegisters().toArray(); ! save = emitSaveAllRegisters(savedRegisters); } Variable result; LIRFrameState debugInfo = null; if (hotspotLinkage.needsDebugInfo()) {
*** 377,400 **** label = null; } else { result = super.emitForeignCall(hotspotLinkage, debugInfo, args); } ! if (destroysRegisters) { ! if (stub != null) { ! if (stub.preservesRegisters()) { 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 --- 376,395 ---- label = null; } else { result = super.emitForeignCall(hotspotLinkage, debugInfo, args); } ! 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,550 **** public void setDebugInfoBuilder(HotSpotDebugInfoBuilder debugInfoBuilder) { this.debugInfoBuilder = debugInfoBuilder; } @Override ! public SaveRegistersOp createZapRegisters(Register[] zappedRegisters, JavaConstant[] zapValues) { throw GraalError.unimplemented(); } @Override public LIRInstruction createZapArgumentSpace(StackSlot[] zappedStack, JavaConstant[] zapValues) { throw GraalError.unimplemented(); } } --- 532,569 ---- public void setDebugInfoBuilder(HotSpotDebugInfoBuilder debugInfoBuilder) { this.debugInfoBuilder = debugInfoBuilder; } @Override ! 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 >