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
getName()90     public String getName() {
91         return "community";
92     }
93 
94     @Override
getArchitecture()95     public Class<? extends Architecture> getArchitecture() {
96         return AArch64.class;
97     }
98 
99     @Override
100     @SuppressWarnings("try")
createBackend(HotSpotGraalRuntimeProvider graalRuntime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host)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 
createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider)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 
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(OptionValues options, Providers p, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider)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 
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