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.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 89 public String getName() { 90 return "community"; 91 } 92 93 @Override 94 public Class<? extends Architecture> getArchitecture() { 95 return AArch64.class; 96 } 97 98 @Override 99 @SuppressWarnings("try") 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(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider); 148 } 149 try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { 150 plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes); 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 } 160 try (InitTimer rt = timer("instantiate backend")) { 161 return createBackend(config, graalRuntime, providers); 162 } 163 } 164 165 protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, 166 HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, 167 HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) { 168 Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements); 169 AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false); 170 return plugins; 171 } 172 173 protected AArch64HotSpotBackend createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { 174 return new AArch64HotSpotBackend(config, runtime, providers); 175 } 176 177 protected HotSpotRegistersProvider createRegisters() { 178 return new HotSpotRegisters(AArch64HotSpotRegisterConfig.threadRegister, AArch64HotSpotRegisterConfig.heapBaseRegister, sp); 179 } 180 181 protected HotSpotReplacementsImpl createReplacements(OptionValues options, Providers p, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) { 182 return new HotSpotReplacementsImpl(options, p, snippetReflection, bytecodeProvider, p.getCodeCache().getTarget()); 183 } 184 185 protected HotSpotHostForeignCallsProvider createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, 186 HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters) { 187 return new AArch64HotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 188 } 189 190 protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, 191 @SuppressWarnings("unused") Replacements replacements) { 192 AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, SchedulePhase.class); 193 Phase addressLoweringPhase = new AddressLoweringByUsePhase(new AArch64AddressLoweringByUse(new AArch64LIRKindTool())); 194 return new AddressLoweringHotSpotSuitesProvider(suitesCreator, config, runtime, addressLoweringPhase); 195 } 196 197 protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes) { 198 return new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes); 199 } 200 201 protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, 202 HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, TargetDescription target) { 203 return new AArch64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target); 204 } 205 206 protected static Value[] createNativeABICallerSaveRegisters(@SuppressWarnings("unused") GraalHotSpotVMConfig config, RegisterConfig regConfig) { 207 List<Register> callerSave = new ArrayList<>(regConfig.getAllocatableRegisters().asList()); 208 callerSave.remove(AArch64.r19); 209 callerSave.remove(AArch64.r20); 210 callerSave.remove(AArch64.r21); 211 callerSave.remove(AArch64.r22); 212 callerSave.remove(AArch64.r23); 213 callerSave.remove(AArch64.r24); 214 callerSave.remove(AArch64.r25); 215 callerSave.remove(AArch64.r26); 216 callerSave.remove(AArch64.r27); 217 callerSave.remove(AArch64.r28); 218 Value[] nativeABICallerSaveRegisters = new Value[callerSave.size()]; 219 for (int i = 0; i < callerSave.size(); i++) { 220 nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); 221 } 222 return nativeABICallerSaveRegisters; 223 } 224 225 @Override 226 public String toString() { 227 return "AArch64"; 228 } 229 }