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