1 /* 2 * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2018, Red Hat Inc. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 26 package org.graalvm.compiler.hotspot.aarch64; 27 28 import static jdk.vm.ci.aarch64.AArch64.sp; 29 import static jdk.vm.ci.common.InitTimer.timer; 30 31 import java.util.ArrayList; 32 import java.util.Arrays; 33 import java.util.List; 34 35 import org.graalvm.compiler.bytecode.BytecodeProvider; 36 import org.graalvm.compiler.core.aarch64.AArch64AddressLoweringByUse; 37 import org.graalvm.compiler.core.aarch64.AArch64LIRKindTool; 38 import org.graalvm.compiler.core.aarch64.AArch64SuitesCreator; 39 import org.graalvm.compiler.core.common.spi.MetaAccessExtensionProvider; 40 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 41 import org.graalvm.compiler.hotspot.HotSpotBackend; 42 import org.graalvm.compiler.hotspot.HotSpotBackendFactory; 43 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; 44 import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl; 45 import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider; 46 import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider; 47 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider; 48 import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider; 49 import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins; 50 import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider; 51 import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider; 52 import org.graalvm.compiler.hotspot.meta.HotSpotMetaAccessExtensionProvider; 53 import org.graalvm.compiler.hotspot.meta.HotSpotPlatformConfigurationProvider; 54 import org.graalvm.compiler.hotspot.meta.HotSpotProviders; 55 import org.graalvm.compiler.hotspot.meta.HotSpotRegisters; 56 import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; 57 import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider; 58 import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider; 59 import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; 60 import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; 61 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; 62 import org.graalvm.compiler.nodes.spi.PlatformConfigurationProvider; 63 import org.graalvm.compiler.nodes.spi.Replacements; 64 import org.graalvm.compiler.options.OptionValues; 65 import org.graalvm.compiler.phases.Phase; 66 import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase; 67 import org.graalvm.compiler.phases.schedule.SchedulePhase; 68 import org.graalvm.compiler.phases.tiers.CompilerConfiguration; 69 import org.graalvm.compiler.replacements.aarch64.AArch64GraphBuilderPlugins; 70 import org.graalvm.compiler.serviceprovider.ServiceProvider; 71 import org.graalvm.compiler.word.WordTypes; 72 73 import jdk.vm.ci.aarch64.AArch64; 74 import jdk.vm.ci.code.Architecture; 75 import jdk.vm.ci.code.Register; 76 import jdk.vm.ci.code.RegisterConfig; 77 import jdk.vm.ci.code.TargetDescription; 78 import jdk.vm.ci.common.InitTimer; 79 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; 80 import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; 81 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; 82 import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; 83 import jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig; 84 import jdk.vm.ci.meta.Value; 85 import jdk.vm.ci.runtime.JVMCIBackend; 86 87 @ServiceProvider(HotSpotBackendFactory.class) 88 public class AArch64HotSpotBackendFactory extends HotSpotBackendFactory { 89 90 @Override getName()91 public String getName() { 92 return "community"; 93 } 94 95 @Override getArchitecture()96 public Class<? extends Architecture> getArchitecture() { 97 return AArch64.class; 98 } 99 100 @Override 101 @SuppressWarnings("try") createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host)102 public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host) { 103 assert host == null; 104 105 OptionValues options = graalRuntime.getOptions(); 106 JVMCIBackend jvmci = jvmciRuntime.getHostJVMCIBackend(); 107 GraalHotSpotVMConfig config = graalRuntime.getVMConfig(); 108 HotSpotProviders providers; 109 HotSpotRegistersProvider registers; 110 HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmci.getCodeCache(); 111 TargetDescription target = codeCache.getTarget(); 112 HotSpotHostForeignCallsProvider foreignCalls; 113 Value[] nativeABICallerSaveRegisters; 114 HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) jvmci.getMetaAccess(); 115 HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection(); 116 HotSpotConstantFieldProvider constantFieldProvider = new HotSpotGraalConstantFieldProvider(config, metaAccess); 117 HotSpotLoweringProvider lowerer; 118 HotSpotStampProvider stampProvider; 119 HotSpotPlatformConfigurationProvider platformConfigurationProvider; 120 HotSpotMetaAccessExtensionProvider metaAccessExtensionProvider; 121 HotSpotSnippetReflectionProvider snippetReflection; 122 HotSpotReplacementsImpl replacements; 123 HotSpotSuitesProvider suites; 124 HotSpotWordTypes wordTypes; 125 Plugins plugins; 126 BytecodeProvider bytecodeProvider; 127 try (InitTimer t = timer("create providers")) { 128 try (InitTimer rt = timer("create HotSpotRegisters provider")) { 129 registers = createRegisters(); 130 } 131 try (InitTimer rt = timer("create NativeABICallerSaveRegisters")) { 132 nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig()); 133 } 134 try (InitTimer rt = timer("create WordTypes")) { 135 wordTypes = createWordTypes(metaAccess, target); 136 } 137 try (InitTimer rt = timer("create ForeignCalls provider")) { 138 foreignCalls = createForeignCalls(jvmciRuntime, graalRuntime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 139 } 140 try (InitTimer rt = timer("create stamp provider")) { 141 stampProvider = createStampProvider(); 142 } 143 try (InitTimer rt = timer("create platform configuration provider")) { 144 platformConfigurationProvider = createConfigInfoProvider(config, metaAccess); 145 } 146 try (InitTimer rt = timer("create MetaAccessExtensionProvider")) { 147 metaAccessExtensionProvider = createMetaAccessExtensionProvider(); 148 } 149 try (InitTimer rt = timer("create Lowerer provider")) { 150 lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, platformConfigurationProvider, metaAccessExtensionProvider, target); 151 } 152 153 HotSpotProviders p = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, platformConfigurationProvider, 154 metaAccessExtensionProvider); 155 156 try (InitTimer rt = timer("create SnippetReflection provider")) { 157 snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); 158 } 159 try (InitTimer rt = timer("create Bytecode provider")) { 160 bytecodeProvider = createBytecodeProvider(metaAccess, snippetReflection); 161 } 162 try (InitTimer rt = timer("create Replacements provider")) { 163 replacements = createReplacements(target, p, snippetReflection, bytecodeProvider); 164 } 165 try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { 166 plugins = createGraphBuilderPlugins(graalRuntime, compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, 167 graalRuntime.getOptions(), target); 168 replacements.setGraphBuilderPlugins(plugins); 169 } 170 try (InitTimer rt = timer("create Suites provider")) { 171 suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, replacements); 172 } 173 providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, 174 snippetReflection, wordTypes, plugins, platformConfigurationProvider, metaAccessExtensionProvider, config); 175 replacements.setProviders(providers); 176 replacements.maybeInitializeEncoder(options); 177 } 178 try (InitTimer rt = timer("instantiate backend")) { 179 return createBackend(config, graalRuntime, providers); 180 } 181 } 182 createGraphBuilderPlugins(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, OptionValues options, TargetDescription target)183 protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider graalRuntime, 184 CompilerConfiguration compilerConfiguration, 185 GraalHotSpotVMConfig config, 186 HotSpotConstantReflectionProvider constantReflection, 187 HotSpotHostForeignCallsProvider foreignCalls, 188 HotSpotMetaAccessProvider metaAccess, 189 HotSpotSnippetReflectionProvider snippetReflection, 190 HotSpotReplacementsImpl replacements, 191 HotSpotWordTypes wordTypes, 192 OptionValues options, 193 TargetDescription target) { 194 Plugins plugins = HotSpotGraphBuilderPlugins.create(graalRuntime, 195 compilerConfiguration, 196 config, 197 wordTypes, 198 metaAccess, 199 constantReflection, 200 snippetReflection, 201 foreignCalls, 202 replacements, 203 options, 204 target); 205 AArch64GraphBuilderPlugins.register(plugins, replacements, false, // 206 /* registerForeignCallMath */true, /* emitJDK9StringSubstitutions */true, config.useFMAIntrinsics); 207 return plugins; 208 } 209 createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers)210 protected AArch64HotSpotBackend createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { 211 return new AArch64HotSpotBackend(config, runtime, providers); 212 } 213 createRegisters()214 protected HotSpotRegistersProvider createRegisters() { 215 return new HotSpotRegisters(AArch64HotSpotRegisterConfig.threadRegister, AArch64HotSpotRegisterConfig.heapBaseRegister, sp); 216 } 217 createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters)218 protected HotSpotHostForeignCallsProvider createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, 219 HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters) { 220 return new AArch64HotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 221 } 222 createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, @SuppressWarnings(R) Replacements replacements)223 protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, 224 @SuppressWarnings("unused") Replacements replacements) { 225 AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, Arrays.asList(SchedulePhase.class)); 226 Phase addressLoweringPhase = new AddressLoweringByUsePhase(new AArch64AddressLoweringByUse(new AArch64LIRKindTool())); 227 return new AddressLoweringHotSpotSuitesProvider(suitesCreator, config, runtime, addressLoweringPhase); 228 } 229 createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, MetaAccessExtensionProvider metaAccessExtensionProvider, TargetDescription target)230 protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, 231 HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, PlatformConfigurationProvider platformConfig, 232 MetaAccessExtensionProvider metaAccessExtensionProvider, 233 TargetDescription target) { 234 return new AArch64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, platformConfig, metaAccessExtensionProvider, target); 235 } 236 createNativeABICallerSaveRegisters(@uppressWarningsR) GraalHotSpotVMConfig config, RegisterConfig regConfig)237 protected static Value[] createNativeABICallerSaveRegisters(@SuppressWarnings("unused") GraalHotSpotVMConfig config, RegisterConfig regConfig) { 238 List<Register> callerSave = new ArrayList<>(regConfig.getAllocatableRegisters().asList()); 239 callerSave.remove(AArch64.r19); 240 callerSave.remove(AArch64.r20); 241 callerSave.remove(AArch64.r21); 242 callerSave.remove(AArch64.r22); 243 callerSave.remove(AArch64.r23); 244 callerSave.remove(AArch64.r24); 245 callerSave.remove(AArch64.r25); 246 callerSave.remove(AArch64.r26); 247 callerSave.remove(AArch64.r27); 248 callerSave.remove(AArch64.r28); 249 Value[] nativeABICallerSaveRegisters = new Value[callerSave.size()]; 250 for (int i = 0; i < callerSave.size(); i++) { 251 nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); 252 } 253 return nativeABICallerSaveRegisters; 254 } 255 256 @Override toString()257 public String toString() { 258 return "AArch64"; 259 } 260 } 261