1 /* 2 * Copyright (c) 2013, 2016, 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.LoweringProvider; 60 import org.graalvm.compiler.nodes.spi.Replacements; 61 import org.graalvm.compiler.options.OptionValues; 62 import org.graalvm.compiler.phases.Phase; 63 import org.graalvm.compiler.phases.common.AddressLoweringByUsePhase; 64 import org.graalvm.compiler.phases.schedule.SchedulePhase; 65 import org.graalvm.compiler.phases.tiers.CompilerConfiguration; 66 import org.graalvm.compiler.phases.util.Providers; 67 import org.graalvm.compiler.replacements.aarch64.AArch64GraphBuilderPlugins; 68 import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider; 69 import org.graalvm.compiler.serviceprovider.ServiceProvider; 70 import org.graalvm.compiler.word.WordTypes; 71 72 import jdk.vm.ci.aarch64.AArch64; 73 import jdk.vm.ci.code.Architecture; 74 import jdk.vm.ci.code.Register; 75 import jdk.vm.ci.code.RegisterConfig; 76 import jdk.vm.ci.code.TargetDescription; 77 import jdk.vm.ci.common.InitTimer; 78 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; 79 import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider; 80 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; 81 import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider; 82 import jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig; 83 import jdk.vm.ci.meta.Value; 84 import jdk.vm.ci.runtime.JVMCIBackend; 85 86 @ServiceProvider(HotSpotBackendFactory.class) 87 public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory { 88 89 @Override 90 public String getName() { 91 return "community"; 92 } 93 94 @Override 95 public Class<? extends Architecture> getArchitecture() { 96 return AArch64.class; 97 } 98 99 @Override 100 @SuppressWarnings("try") 101 public HotSpotBackend createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host) { 102 assert host == null; 103 104 JVMCIBackend jvmci = jvmciRuntime.getHostJVMCIBackend(); 105 GraalHotSpotVMConfig config = graalRuntime.getVMConfig(); 106 HotSpotProviders providers; 107 HotSpotRegistersProvider registers; 108 HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmci.getCodeCache(); 109 TargetDescription target = codeCache.getTarget(); 110 HotSpotHostForeignCallsProvider foreignCalls; 111 Value[] nativeABICallerSaveRegisters; 112 HotSpotMetaAccessProvider metaAccess = (HotSpotMetaAccessProvider) jvmci.getMetaAccess(); 113 HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection(); 114 HotSpotConstantFieldProvider constantFieldProvider = new HotSpotGraalConstantFieldProvider(config, metaAccess); 115 HotSpotLoweringProvider lowerer; 116 HotSpotSnippetReflectionProvider snippetReflection; 117 HotSpotReplacementsImpl replacements; 118 HotSpotSuitesProvider suites; 119 HotSpotWordTypes wordTypes; 120 Plugins plugins; 121 BytecodeProvider bytecodeProvider; 122 try (InitTimer t = timer("create providers")) { 123 try (InitTimer rt = timer("create HotSpotRegisters provider")) { 124 registers = createRegisters(); 125 } 126 try (InitTimer rt = timer("create NativeABICallerSaveRegisters")) { 127 nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig()); 128 } 129 try (InitTimer rt = timer("create WordTypes")) { 130 wordTypes = new HotSpotWordTypes(metaAccess, target.wordJavaKind); 131 } 132 try (InitTimer rt = timer("create ForeignCalls provider")) { 133 foreignCalls = createForeignCalls(jvmciRuntime, graalRuntime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 134 } 135 try (InitTimer rt = timer("create Lowerer provider")) { 136 lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target); 137 } 138 HotSpotStampProvider stampProvider = new HotSpotStampProvider(); 139 Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider); 140 141 try (InitTimer rt = timer("create SnippetReflection provider")) { 142 snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); 143 } 144 try (InitTimer rt = timer("create Bytecode provider")) { 145 bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection); 146 } 147 try (InitTimer rt = timer("create Replacements provider")) { 148 replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider); 149 } 150 try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { 151 plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes, stampProvider); 152 replacements.setGraphBuilderPlugins(plugins); 153 } 154 try (InitTimer rt = timer("create Suites provider")) { 155 suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, replacements); 156 } 157 providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, 158 snippetReflection, wordTypes, 159 plugins); 160 } 161 try (InitTimer rt = timer("instantiate backend")) { 162 return createBackend(config, graalRuntime, providers); 163 } 164 } 165 166 protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, 167 HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, 168 HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) { 169 Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider, 170 replacements); 171 AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false); 172 return plugins; 173 } 174 175 protected AArch64HotSpotBackend createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { 176 return new AArch64HotSpotBackend(config, runtime, providers); 177 } 178 179 protected HotSpotRegistersProvider createRegisters() { 180 return new HotSpotRegisters(AArch64HotSpotRegisterConfig.threadRegister, AArch64HotSpotRegisterConfig.heapBaseRegister, sp); 181 } 182 183 protected HotSpotReplacementsImpl createReplacements(OptionValues options, Providers p, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) { 184 return new HotSpotReplacementsImpl(options, p, snippetReflection, bytecodeProvider, p.getCodeCache().getTarget()); 185 } 186 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 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 199 protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes) { 200 return new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes); 201 } 202 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 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 228 public String toString() { 229 return "AArch64"; 230 } 231 }