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.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.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.HotSpotGCProvider; 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.HotSpotProviders; 53 import org.graalvm.compiler.hotspot.meta.HotSpotRegisters; 54 import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider; 55 import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider; 56 import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider; 57 import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; 58 import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; 59 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; 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.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 extends 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 HotSpotStampProvider stampProvider; 116 HotSpotGCProvider gc; 117 HotSpotSnippetReflectionProvider snippetReflection; 118 HotSpotReplacementsImpl replacements; 119 HotSpotSuitesProvider suites; 120 HotSpotWordTypes wordTypes; 121 Plugins plugins; 122 BytecodeProvider bytecodeProvider; 123 try (InitTimer t = timer("create providers")) { 124 try (InitTimer rt = timer("create HotSpotRegisters provider")) { 125 registers = createRegisters(); 126 } 127 try (InitTimer rt = timer("create NativeABICallerSaveRegisters")) { 128 nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig()); 129 } 130 try (InitTimer rt = timer("create WordTypes")) { 131 wordTypes = createWordTypes(metaAccess, target); 132 } 133 try (InitTimer rt = timer("create ForeignCalls provider")) { 134 foreignCalls = createForeignCalls(jvmciRuntime, graalRuntime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 135 } 136 try (InitTimer rt = timer("create Lowerer provider")) { 137 lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target); 138 } 139 try (InitTimer rt = timer("create stamp provider")) { 140 stampProvider = createStampProvider(); 141 } 142 try (InitTimer rt = timer("create GC provider")) { 143 gc = createGCProvider(config); 144 } 145 146 Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, gc); 147 148 try (InitTimer rt = timer("create SnippetReflection provider")) { 149 snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes); 150 } 151 try (InitTimer rt = timer("create Bytecode provider")) { 152 bytecodeProvider = createBytecodeProvider(metaAccess, snippetReflection); 153 } 154 try (InitTimer rt = timer("create Replacements provider")) { 155 replacements = createReplacements(target, p, snippetReflection, bytecodeProvider); 156 } 157 try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { 158 plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, graalRuntime.getOptions()); 159 replacements.setGraphBuilderPlugins(plugins); 160 } 161 try (InitTimer rt = timer("create Suites provider")) { 162 suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, replacements); 163 } 164 providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, 165 snippetReflection, wordTypes, plugins, gc); 166 replacements.setProviders(providers); 167 } 168 try (InitTimer rt = timer("instantiate backend")) { 169 return createBackend(config, graalRuntime, providers); 170 } 171 } 172 173 protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, 174 HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, 175 HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, OptionValues options) { 176 Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements, options); 177 AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false, // 178 /* registerMathPlugins */true); 179 return plugins; 180 } 181 182 protected AArch64HotSpotBackend createBackend(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { 183 return new AArch64HotSpotBackend(config, runtime, providers); 184 } 185 186 protected HotSpotRegistersProvider createRegisters() { 187 return new HotSpotRegisters(AArch64HotSpotRegisterConfig.threadRegister, AArch64HotSpotRegisterConfig.heapBaseRegister, sp); 188 } 189 190 protected HotSpotHostForeignCallsProvider createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, 191 HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters) { 192 return new AArch64HotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters); 193 } 194 195 protected HotSpotSuitesProvider createSuites(GraalHotSpotVMConfig config, HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, Plugins plugins, 196 @SuppressWarnings("unused") Replacements replacements) { 197 AArch64SuitesCreator suitesCreator = new AArch64SuitesCreator(compilerConfiguration, plugins, Arrays.asList(SchedulePhase.class)); 198 Phase addressLoweringPhase = new AddressLoweringByUsePhase(new AArch64AddressLoweringByUse(new AArch64LIRKindTool())); 199 return new AddressLoweringHotSpotSuitesProvider(suitesCreator, config, runtime, addressLoweringPhase); 200 } 201 202 protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls, 203 HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, TargetDescription target) { 204 return new AArch64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target); 205 } 206 207 protected static Value[] createNativeABICallerSaveRegisters(@SuppressWarnings("unused") GraalHotSpotVMConfig config, RegisterConfig regConfig) { 208 List<Register> callerSave = new ArrayList<>(regConfig.getAllocatableRegisters().asList()); 209 callerSave.remove(AArch64.r19); 210 callerSave.remove(AArch64.r20); 211 callerSave.remove(AArch64.r21); 212 callerSave.remove(AArch64.r22); 213 callerSave.remove(AArch64.r23); 214 callerSave.remove(AArch64.r24); 215 callerSave.remove(AArch64.r25); 216 callerSave.remove(AArch64.r26); 217 callerSave.remove(AArch64.r27); 218 callerSave.remove(AArch64.r28); 219 Value[] nativeABICallerSaveRegisters = new Value[callerSave.size()]; 220 for (int i = 0; i < callerSave.size(); i++) { 221 nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); 222 } 223 return nativeABICallerSaveRegisters; 224 } 225 226 @Override 227 public String toString() { 228 return "AArch64"; 229 } 230 }