1 /* 2 * Copyright (c) 2013, 2018, 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.List; 33 34 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; 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.hotspot.GraalHotSpotVMConfig; 40 import org.graalvm.compiler.hotspot.HotSpotBackend; 41 import org.graalvm.compiler.hotspot.HotSpotBackendFactory; 42 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; 43 import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl; 44 import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider; 45 import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider; 46 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider; 47 import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider; 48 import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins; 49 import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider; 50 import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider; 51 import org.graalvm.compiler.hotspot.meta.HotSpotProviders; 52 import org.graalvm.compiler.hotspot.meta.HotSpotRegisters; 53 import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; 54 import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider; 55 import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider; 56 import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; 57 import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; 58 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; 59 import org.graalvm.compiler.nodes.spi.Replacements; 60 import org.graalvm.compiler.options.OptionValues; 61 import org.graalvm.compiler.phases.Phase; 62 import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase; 63 import org.graalvm.compiler.phases.schedule.SchedulePhase; 64 import org.graalvm.compiler.phases.tiers.CompilerConfiguration; 65 import org.graalvm.compiler.phases.util.Providers; 66 import org.graalvm.compiler.replacements.aarch64.AArch64GraphBuilderPlugins; 67 import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider; 68 import org.graalvm.compiler.serviceprovider.ServiceProvider; 69 import org.graalvm.compiler.word.WordTypes; 70 71 import jdk.vm.ci.aarch64.AArch64; 72 import jdk.vm.ci.code.Architecture; 73 import jdk.vm.ci.code.Register; 74 import jdk.vm.ci.code.RegisterConfig; 75 import jdk.vm.ci.code.TargetDescription; 76 import jdk.vm.ci.common.InitTimer; 77 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; 78 import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; 79 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; 80 import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; 81 import jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig; 82 import jdk.vm.ci.meta.Value; 83 import jdk.vm.ci.runtime.JVMCIBackend; 84 85 @ServiceProvider(HotSpotBackendFactory.class) 86 public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory { 87 88 @Override getName()89 public String getName() { 90 return "community"; 91 } 92 93 @Override getArchitecture()94 public Class<? extends Architecture> getArchitecture() { 95 return AArch64.class; 96 } 97 98 @Override 99 @SuppressWarnings("try") createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host)100 public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host) { 101 assert host == null; 102 103 JVMCIBackend jvmci = jvmciRuntime.getHostJVMCIBackend(); 104 GraalHotSpotVMConfig config = graalRuntime.getVMConfig(); 105 HotSpotProviders providers; 106 HotSpotRegistersProvider registers; 107 HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmci.getCodeCache(); 108 TargetDescription target = codeCache.getTarget(); 109 HotSpotHostForeignCallsProvider foreignCalls; 110 Value[] nativeABICallerSaveRegisters; 111 HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) jvmci.getMetaAccess(); 112 HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection(); 113 HotSpotConstantFieldProvider constantFieldProvider = new HotSpotGraalConstantFieldProvider(config, metaAccess); 114 HotSpotLoweringProvider lowerer; 115 HotSpotSnippetReflectionProvider snippetReflection; 116 HotSpotReplacementsImpl replacements; 117 HotSpotSuitesProvider suites; 118 HotSpotWordTypes wordTypes; 119 Plugins plugins; 120 BytecodeProvider bytecodeProvider; 121 try (InitTimer t = timer("create providers")) { 122 try (InitTimer rt = timer("create HotSpotRegisters provider")) { 123 registers = createRegisters(); 124 } 125 try (InitTimer rt = timer("create NativeABICallerSaveRegisters")) { 126 nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig()); 127 } 128 try (InitTimer rt = timer("create WordTypes")) { 129 wordTypes = new HotSpotWordTypes(metaAccess, target.wordJavaKind); 130 } 131 try (InitTimer rt = timer("create ForeignCalls provider")) { 132 foreignCalls = createForeignCalls(jvmciRuntime, graalRuntime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 133 } 134 try (InitTimer rt = timer("create Lowerer provider")) { 135 lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target); 136 } 137 HotSpotStampProvider stampProvider = new HotSpotStampProvider(); 138 Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider); 139 140 try (InitTimer rt = timer("create SnippetReflection provider")) { 141 snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); 142 } 143 try (InitTimer rt = timer("create Bytecode provider")) { 144 bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection); 145 } 146 try (InitTimer rt = timer("create Replacements provider")) { 147 replacements = createReplacements(p, snippetReflection, bytecodeProvider); 148 } 149 try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { 150 plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, graalRuntime.getOptions()); 151 replacements.setGraphBuilderPlugins(plugins); 152 } 153 try (InitTimer rt = timer("create Suites provider")) { 154 suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, replacements); 155 } 156 providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, 157 snippetReflection, wordTypes, 158 plugins); 159 replacements.setProviders(providers); 160 } 161 try (InitTimer rt = timer("instantiate backend")) { 162 return createBackend(config, graalRuntime, providers); 163 } 164 } 165 createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, OptionValues options)166 protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, 167 HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, 168 HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, OptionValues options) { 169 Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements, options); 170 AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false, // 171 /* registerMathPlugins */true); 172 return plugins; 173 } 174 createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers)175 protected AArch64HotSpotBackend createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { 176 return new AArch64HotSpotBackend(config, runtime, providers); 177 } 178 createRegisters()179 protected HotSpotRegistersProvider createRegisters() { 180 return new HotSpotRegisters(AArch64HotSpotRegisterConfig.threadRegister, AArch64HotSpotRegisterConfig.heapBaseRegister, sp); 181 } 182 createReplacements(Providers p, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider)183 protected HotSpotReplacementsImpl createReplacements(Providers p, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) { 184 return new HotSpotReplacementsImpl(p, snippetReflection, bytecodeProvider, p.getCodeCache().getTarget()); 185 } 186 createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters)187 protected HotSpotHostForeignCallsProvider createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, 188 HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters) { 189 return new AArch64HotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 190 } 191 createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, @SuppressWarnings(R) Replacements replacements)192 protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, 193 @SuppressWarnings("unused") Replacements replacements) { 194 AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, SchedulePhase.class); 195 Phase addressLoweringPhase = new AddressLoweringByUsePhase(new AArch64AddressLoweringByUse(new AArch64LIRKindTool())); 196 return new AddressLoweringHotSpotSuitesProvider(suitesCreator, config, runtime, addressLoweringPhase); 197 } 198 createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes)199 protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes) { 200 return new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes); 201 } 202 createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, TargetDescription target)203 protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, 204 HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, TargetDescription target) { 205 return new AArch64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target); 206 } 207 createNativeABICallerSaveRegisters(@uppressWarningsR) GraalHotSpotVMConfig config, RegisterConfig regConfig)208 protected static Value[] createNativeABICallerSaveRegisters(@SuppressWarnings("unused") GraalHotSpotVMConfig config, RegisterConfig regConfig) { 209 List<Register> callerSave = new ArrayList<>(regConfig.getAllocatableRegisters().asList()); 210 callerSave.remove(AArch64.r19); 211 callerSave.remove(AArch64.r20); 212 callerSave.remove(AArch64.r21); 213 callerSave.remove(AArch64.r22); 214 callerSave.remove(AArch64.r23); 215 callerSave.remove(AArch64.r24); 216 callerSave.remove(AArch64.r25); 217 callerSave.remove(AArch64.r26); 218 callerSave.remove(AArch64.r27); 219 callerSave.remove(AArch64.r28); 220 Value[] nativeABICallerSaveRegisters = new Value[callerSave.size()]; 221 for (int i = 0; i < callerSave.size(); i++) { 222 nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); 223 } 224 return nativeABICallerSaveRegisters; 225 } 226 227 @Override toString()228 public String toString() { 229 return "AArch64"; 230 } 231 } 232