blob: 635fde39bfaba793ead98e270264a5ecc8a15ef2 [file] [log] [blame]
Shih-wei Liaod1fec812012-02-13 09:51:10 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "compiler_llvm.h"
18
Shih-wei Liao26e93072012-05-30 19:13:08 -070019#include "backend_options.h"
Shih-wei Liaoc4c98812012-03-10 21:55:51 -080020#include "class_linker.h"
Logan Chien8b977d32012-02-21 19:14:55 +080021#include "compilation_unit.h"
Logan Chienf7015fd2012-03-18 01:19:37 +080022#include "compiled_method.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080023#include "compiler.h"
Shih-wei Liaoc4c98812012-03-10 21:55:51 -080024#include "dex_cache.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080025#include "ir_builder.h"
Logan Chien88894ee2012-02-13 16:42:22 +080026#include "jni_compiler.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080027#include "method_compiler.h"
Logan Chien4dd96f52012-02-29 01:26:58 +080028#include "oat_compilation_unit.h"
Logan Chien0c717dd2012-03-28 18:31:07 +080029#include "oat_file.h"
Logan Chien7f767612012-03-01 18:54:49 +080030#include "stl_util.h"
TDYa127eead4ac2012-06-03 07:15:25 -070031#include "stub_compiler.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080032
Logan Chiendd7cf5b2012-03-01 12:55:19 +080033#include <llvm/LinkAllPasses.h>
34#include <llvm/LinkAllVMCore.h>
Logan Chien013b6f22012-03-02 17:20:33 +080035#include <llvm/Support/ManagedStatic.h>
Logan Chien8b977d32012-02-21 19:14:55 +080036#include <llvm/Support/TargetSelect.h>
37#include <llvm/Support/Threading.h>
38
Logan Chien013b6f22012-03-02 17:20:33 +080039namespace llvm {
40 extern bool TimePassesIsEnabled;
41}
42
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080043namespace {
Logan Chien8b977d32012-02-21 19:14:55 +080044
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080045pthread_once_t llvm_initialized = PTHREAD_ONCE_INIT;
46
47void InitializeLLVM() {
Logan Chienc3f8fa52012-05-11 11:23:39 +080048 // Initialize LLVM internal data structure for multithreading
49 llvm::llvm_start_multithreaded();
50
Logan Chien013b6f22012-03-02 17:20:33 +080051 // NOTE: Uncomment following line to show the time consumption of LLVM passes
52 //llvm::TimePassesIsEnabled = true;
53
Shih-wei Liao26e93072012-05-30 19:13:08 -070054 // Initialize LLVM target-specific options.
55 art::compiler_llvm::InitialBackendOptions();
Logan Chienc3f8fa52012-05-11 11:23:39 +080056
Shih-wei Liao1335a952012-07-23 18:03:00 -070057 // Initialize LLVM target, MC subsystem, asm printer, and asm parser.
58#if defined(ART_TARGET)
59 // Don't initialize all targets on device. Just initialize the device's native target
60 llvm::InitializeNativeTarget();
61 llvm::InitializeNativeTargetAsmPrinter();
62 llvm::InitializeNativeTargetAsmParser();
63#else
Logan Chien8b977d32012-02-21 19:14:55 +080064 llvm::InitializeAllTargets();
65 llvm::InitializeAllTargetMCs();
66 llvm::InitializeAllAsmPrinters();
67 llvm::InitializeAllAsmParsers();
Shih-wei Liao1335a952012-07-23 18:03:00 -070068#endif
Logan Chien8b977d32012-02-21 19:14:55 +080069
Logan Chiendd7cf5b2012-03-01 12:55:19 +080070 // Initialize LLVM optimization passes
71 llvm::PassRegistry &registry = *llvm::PassRegistry::getPassRegistry();
72
73 llvm::initializeCore(registry);
74 llvm::initializeScalarOpts(registry);
75 llvm::initializeIPO(registry);
76 llvm::initializeAnalysis(registry);
77 llvm::initializeIPA(registry);
78 llvm::initializeTransformUtils(registry);
79 llvm::initializeInstCombine(registry);
80 llvm::initializeInstrumentation(registry);
81 llvm::initializeTarget(registry);
Logan Chien8b977d32012-02-21 19:14:55 +080082}
83
Logan Chienf1306552012-03-16 11:17:53 +080084// The Guard to Shutdown LLVM
Logan Chienaeb53032012-03-18 02:29:38 +080085// llvm::llvm_shutdown_obj llvm_guard;
86// TODO: We are commenting out this line because this will cause SEGV from
87// time to time.
88// Two reasons: (1) the order of the destruction of static objects, or
89// (2) dlopen/dlclose side-effect on static objects.
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080090
91} // anonymous namespace
92
93
94namespace art {
95namespace compiler_llvm {
Shih-wei Liaod1fec812012-02-13 09:51:10 -080096
97
Logan Chiene75a8cc2012-02-24 12:26:43 +080098llvm::Module* makeLLVMModuleContents(llvm::Module* module);
Logan Chien42e0e152012-01-13 15:42:36 +080099
100
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800101CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
Logan Chien971bf3f2012-05-01 15:47:55 +0800102 : compiler_(compiler), insn_set_(insn_set),
103 num_cunits_lock_("compilation unit counter lock"), num_cunits_(0),
104 plt_(insn_set) {
Shih-wei Liaofc34adb2012-03-07 08:51:44 -0800105
106 // Initialize LLVM libraries
107 pthread_once(&llvm_initialized, InitializeLLVM);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800108}
109
110
111CompilerLLVM::~CompilerLLVM() {
112}
113
114
Logan Chien971bf3f2012-05-01 15:47:55 +0800115CompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
116 MutexLock GUARD(num_cunits_lock_);
117 return new CompilationUnit(this, num_cunits_++);
Logan Chiendf576142012-03-20 17:36:32 +0800118}
119
120
Logan Chien7f767612012-03-01 18:54:49 +0800121CompiledMethod* CompilerLLVM::
122CompileDexMethod(OatCompilationUnit* oat_compilation_unit) {
Logan Chien971bf3f2012-05-01 15:47:55 +0800123 UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
Logan Chien8ba2fc52012-04-23 09:10:46 +0800124
Logan Chien8b977d32012-02-21 19:14:55 +0800125 UniquePtr<MethodCompiler> method_compiler(
Logan Chien971bf3f2012-05-01 15:47:55 +0800126 new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));
Logan Chien8b977d32012-02-21 19:14:55 +0800127
Logan Chien7f767612012-03-01 18:54:49 +0800128 return method_compiler->Compile();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800129}
Logan Chien83426162011-12-09 09:29:50 +0800130
131
Logan Chien7f767612012-03-01 18:54:49 +0800132CompiledMethod* CompilerLLVM::
133CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
Logan Chien971bf3f2012-05-01 15:47:55 +0800134 UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
Logan Chien8ba2fc52012-04-23 09:10:46 +0800135
Logan Chien8b977d32012-02-21 19:14:55 +0800136 UniquePtr<JniCompiler> jni_compiler(
Logan Chien971bf3f2012-05-01 15:47:55 +0800137 new JniCompiler(cunit.get(), *compiler_, oat_compilation_unit));
Logan Chien8b977d32012-02-21 19:14:55 +0800138
Logan Chien7f767612012-03-01 18:54:49 +0800139 return jni_compiler->Compile();
Logan Chien88894ee2012-02-13 16:42:22 +0800140}
141
142
Logan Chienf04364f2012-02-10 12:01:39 +0800143CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
144 char const *shorty) {
Logan Chien971bf3f2012-05-01 15:47:55 +0800145 UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
Logan Chien8ba2fc52012-04-23 09:10:46 +0800146
TDYa127eead4ac2012-06-03 07:15:25 -0700147 UniquePtr<StubCompiler> stub_compiler(
Logan Chien971bf3f2012-05-01 15:47:55 +0800148 new StubCompiler(cunit.get(), *compiler_));
Logan Chien8b977d32012-02-21 19:14:55 +0800149
Logan Chien7a2a23a2012-06-06 11:01:00 +0800150 return stub_compiler->CreateInvokeStub(is_static, shorty);
151}
TDYa127eead4ac2012-06-03 07:15:25 -0700152
TDYa127eead4ac2012-06-03 07:15:25 -0700153
Logan Chien7a2a23a2012-06-06 11:01:00 +0800154CompiledInvokeStub* CompilerLLVM::CreateProxyStub(char const *shorty) {
Logan Chien971bf3f2012-05-01 15:47:55 +0800155 UniquePtr<CompilationUnit> cunit(AllocateCompilationUnit());
Logan Chien7a2a23a2012-06-06 11:01:00 +0800156
157 UniquePtr<StubCompiler> stub_compiler(
Logan Chien971bf3f2012-05-01 15:47:55 +0800158 new StubCompiler(cunit.get(), *compiler_));
Logan Chien7a2a23a2012-06-06 11:01:00 +0800159
160 return stub_compiler->CreateProxyStub(shorty);
Logan Chienf04364f2012-02-10 12:01:39 +0800161}
162
Logan Chien83426162011-12-09 09:29:50 +0800163} // namespace compiler_llvm
164} // namespace art
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800165
Logan Chien106b2a02012-03-18 04:41:38 +0800166inline static art::compiler_llvm::CompilerLLVM* ContextOf(art::Compiler& compiler) {
167 void *compiler_context = compiler.GetCompilerContext();
168 CHECK(compiler_context != NULL);
169 return reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler_context);
170}
171
172inline static const art::compiler_llvm::CompilerLLVM* ContextOf(const art::Compiler& compiler) {
173 void *compiler_context = compiler.GetCompilerContext();
174 CHECK(compiler_context != NULL);
175 return reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler_context);
176}
177
178extern "C" void ArtInitCompilerContext(art::Compiler& compiler) {
179 CHECK(compiler.GetCompilerContext() == NULL);
180
181 art::compiler_llvm::CompilerLLVM* compiler_llvm =
182 new art::compiler_llvm::CompilerLLVM(&compiler,
183 compiler.GetInstructionSet());
184
185 compiler.SetCompilerContext(compiler_llvm);
186}
187
Logan Chien971bf3f2012-05-01 15:47:55 +0800188extern "C" void ArtUnInitCompilerContext(art::Compiler& compiler) {
189 delete ContextOf(compiler);
190 compiler.SetCompilerContext(NULL);
191}
192
Elliott Hughes3fa1b7e2012-03-13 17:06:22 -0700193extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800194 const art::DexFile::CodeItem* code_item,
195 uint32_t access_flags, uint32_t method_idx,
TDYa12750b69e32012-06-26 18:11:27 -0700196 art::ClassLoader* class_loader,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800197 const art::DexFile& dex_file)
198{
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800199 art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
200 art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
201
202 art::OatCompilationUnit oat_compilation_unit(
203 class_loader, class_linker, dex_file, *dex_cache, code_item,
204 method_idx, access_flags);
TDYa1270200d072012-04-17 20:55:08 -0700205 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
206 art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&oat_compilation_unit);
TDYa1270200d072012-04-17 20:55:08 -0700207 return result;
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800208}
209
210extern "C" art::CompiledMethod* ArtJniCompileMethod(art::Compiler& compiler,
211 uint32_t access_flags, uint32_t method_idx,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800212 const art::DexFile& dex_file) {
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800213 art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
214 art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
215
216 art::OatCompilationUnit oat_compilation_unit(
Shih-wei Liaob1ab7df2012-03-29 13:53:46 -0700217 NULL, class_linker, dex_file, *dex_cache, NULL,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800218 method_idx, access_flags);
219
Logan Chien106b2a02012-03-18 04:41:38 +0800220 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
Elliott Hughes6f4976c2012-03-13 21:19:01 -0700221 art::CompiledMethod* result = compiler_llvm->CompileNativeMethod(&oat_compilation_unit);
Elliott Hughes13b835a2012-03-13 19:45:22 -0700222 return result;
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800223}
224
Logan Chien7a2a23a2012-06-06 11:01:00 +0800225extern "C" art::CompiledInvokeStub* ArtCreateInvokeStub(art::Compiler& compiler,
226 bool is_static,
227 const char* shorty,
228 uint32_t shorty_len) {
TDYa1270200d072012-04-17 20:55:08 -0700229 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
230 art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty);
TDYa1270200d072012-04-17 20:55:08 -0700231 return result;
Logan Chien106b2a02012-03-18 04:41:38 +0800232}
233
Logan Chien7a2a23a2012-06-06 11:01:00 +0800234extern "C" art::CompiledInvokeStub* ArtCreateProxyStub(art::Compiler& compiler,
235 const char* shorty,
236 uint32_t shorty_len) {
237 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
238 art::CompiledInvokeStub* result = compiler_llvm->CreateProxyStub(shorty);
Logan Chien7a2a23a2012-06-06 11:01:00 +0800239 return result;
240}
241
Logan Chien106b2a02012-03-18 04:41:38 +0800242extern "C" void compilerLLVMSetBitcodeFileName(art::Compiler& compiler,
243 std::string const& filename) {
244 ContextOf(compiler)->SetBitcodeFileName(filename);
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800245}