blob: 3fbc55a41b616778467f2527f09a261765940df9 [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"
Brian Carlstrom265091e2013-01-30 14:08:26 -080020#include "base/stl_util.h"
Shih-wei Liaoc4c98812012-03-10 21:55:51 -080021#include "class_linker.h"
Logan Chienf7015fd2012-03-18 01:19:37 +080022#include "compiled_method.h"
Ian Rogers1212a022013-03-04 10:48:41 -080023#include "compiler/driver/compiler_driver.h"
Ian Rogers89756f22013-03-04 16:40:02 -080024#include "compiler/driver/dex_compilation_unit.h"
Ian Rogers4c1c2832013-03-04 18:30:13 -080025#include "compiler/invoke_stubs/portable/stub_compiler.h"
Ian Rogers02113782013-03-04 12:12:48 -080026#include "compiler/jni/portable/jni_compiler.h"
Brian Carlstrom265091e2013-01-30 14:08:26 -080027#include "globals.h"
Ian Rogers4c1c2832013-03-04 18:30:13 -080028#include "ir_builder.h"
Brian Carlstrom641ce032013-01-31 15:21:37 -080029#include "llvm_compilation_unit.h"
Logan Chien0c717dd2012-03-28 18:31:07 +080030#include "oat_file.h"
Shih-wei Liao21d28f52012-06-12 05:55:00 -070031#include "utils_llvm.h"
TDYa127ce4cc0d2012-11-18 16:59:53 -080032#include "verifier/method_verifier.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080033
Logan Chiendd7cf5b2012-03-01 12:55:19 +080034#include <llvm/LinkAllPasses.h>
35#include <llvm/LinkAllVMCore.h>
Logan Chien013b6f22012-03-02 17:20:33 +080036#include <llvm/Support/ManagedStatic.h>
Logan Chien8b977d32012-02-21 19:14:55 +080037#include <llvm/Support/TargetSelect.h>
38#include <llvm/Support/Threading.h>
39
Shih-wei Liaobb33f2f2012-08-23 13:20:00 -070040namespace art {
Ian Rogers1212a022013-03-04 10:48:41 -080041void CompileOneMethod(CompilerDriver& driver,
buzbeec531cef2012-10-18 07:09:20 -070042 const CompilerBackend compilerBackend,
43 const DexFile::CodeItem* code_item,
44 uint32_t access_flags, InvokeType invoke_type,
TDYa127dc5daa02013-01-09 21:31:37 +080045 uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
buzbeec531cef2012-10-18 07:09:20 -070046 const DexFile& dex_file,
Brian Carlstrom265091e2013-01-30 14:08:26 -080047 llvm::LlvmCompilationUnit* llvm_info);
Shih-wei Liaobb33f2f2012-08-23 13:20:00 -070048}
Shih-wei Liaobb33f2f2012-08-23 13:20:00 -070049
Logan Chien013b6f22012-03-02 17:20:33 +080050namespace llvm {
51 extern bool TimePassesIsEnabled;
52}
53
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080054namespace {
Logan Chien8b977d32012-02-21 19:14:55 +080055
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080056pthread_once_t llvm_initialized = PTHREAD_ONCE_INIT;
57
58void InitializeLLVM() {
Logan Chienc3f8fa52012-05-11 11:23:39 +080059 // Initialize LLVM internal data structure for multithreading
60 llvm::llvm_start_multithreaded();
61
Logan Chien013b6f22012-03-02 17:20:33 +080062 // NOTE: Uncomment following line to show the time consumption of LLVM passes
63 //llvm::TimePassesIsEnabled = true;
64
Shih-wei Liao26e93072012-05-30 19:13:08 -070065 // Initialize LLVM target-specific options.
Ian Rogers4c1c2832013-03-04 18:30:13 -080066 art::llvm::InitialBackendOptions();
Logan Chienc3f8fa52012-05-11 11:23:39 +080067
Shih-wei Liao1335a952012-07-23 18:03:00 -070068 // Initialize LLVM target, MC subsystem, asm printer, and asm parser.
Brian Carlstrom265091e2013-01-30 14:08:26 -080069 if (art::kIsTargetBuild) {
70 // Don't initialize all targets on device. Just initialize the device's native target
71 llvm::InitializeNativeTarget();
72 llvm::InitializeNativeTargetAsmPrinter();
73 llvm::InitializeNativeTargetAsmParser();
74 } else {
75 llvm::InitializeAllTargets();
76 llvm::InitializeAllTargetMCs();
77 llvm::InitializeAllAsmPrinters();
78 llvm::InitializeAllAsmParsers();
79 }
Logan Chien8b977d32012-02-21 19:14:55 +080080
Logan Chiendd7cf5b2012-03-01 12:55:19 +080081 // Initialize LLVM optimization passes
82 llvm::PassRegistry &registry = *llvm::PassRegistry::getPassRegistry();
83
84 llvm::initializeCore(registry);
85 llvm::initializeScalarOpts(registry);
86 llvm::initializeIPO(registry);
87 llvm::initializeAnalysis(registry);
88 llvm::initializeIPA(registry);
89 llvm::initializeTransformUtils(registry);
90 llvm::initializeInstCombine(registry);
91 llvm::initializeInstrumentation(registry);
92 llvm::initializeTarget(registry);
Logan Chien8b977d32012-02-21 19:14:55 +080093}
94
Logan Chienf1306552012-03-16 11:17:53 +080095// The Guard to Shutdown LLVM
Logan Chienaeb53032012-03-18 02:29:38 +080096// llvm::llvm_shutdown_obj llvm_guard;
97// TODO: We are commenting out this line because this will cause SEGV from
98// time to time.
99// Two reasons: (1) the order of the destruction of static objects, or
100// (2) dlopen/dlclose side-effect on static objects.
Shih-wei Liaofc34adb2012-03-07 08:51:44 -0800101
102} // anonymous namespace
103
104
105namespace art {
Ian Rogers4c1c2832013-03-04 18:30:13 -0800106namespace llvm {
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800107
108
Ian Rogers4c1c2832013-03-04 18:30:13 -0800109::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
Logan Chien42e0e152012-01-13 15:42:36 +0800110
111
Ian Rogers1212a022013-03-04 10:48:41 -0800112CompilerLLVM::CompilerLLVM(CompilerDriver* driver, InstructionSet insn_set)
113 : compiler_driver_(driver), insn_set_(insn_set),
Brian Carlstrom265091e2013-01-30 14:08:26 -0800114 next_cunit_id_lock_("compilation unit id lock"), next_cunit_id_(1) {
Shih-wei Liaofc34adb2012-03-07 08:51:44 -0800115
116 // Initialize LLVM libraries
117 pthread_once(&llvm_initialized, InitializeLLVM);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800118}
119
120
121CompilerLLVM::~CompilerLLVM() {
122}
123
124
Brian Carlstrom641ce032013-01-31 15:21:37 -0800125LlvmCompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800126 MutexLock GUARD(Thread::Current(), next_cunit_id_lock_);
127 LlvmCompilationUnit* cunit = new LlvmCompilationUnit(this, next_cunit_id_++);
TDYa127b672d1e2012-06-28 21:21:45 -0700128 if (!bitcode_filename_.empty()) {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800129 cunit->SetBitcodeFileName(StringPrintf("%s-%zu",
130 bitcode_filename_.c_str(),
131 cunit->GetCompilationUnitId()));
TDYa127b672d1e2012-06-28 21:21:45 -0700132 }
133 return cunit;
Logan Chiendf576142012-03-20 17:36:32 +0800134}
135
136
Logan Chien7f767612012-03-01 18:54:49 +0800137CompiledMethod* CompilerLLVM::
Ian Rogers89756f22013-03-04 16:40:02 -0800138CompileDexMethod(DexCompilationUnit* dex_compilation_unit, InvokeType invoke_type) {
Brian Carlstrom641ce032013-01-31 15:21:37 -0800139 UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());
Logan Chien8ba2fc52012-04-23 09:10:46 +0800140
Brian Carlstrom265091e2013-01-30 14:08:26 -0800141 cunit->SetDexCompilationUnit(dex_compilation_unit);
Ian Rogers0d94eb62013-03-06 15:20:50 -0800142 cunit->SetCompilerDriver(compiler_driver_);
Ian Rogersc928de92013-02-27 14:30:44 -0800143 // TODO: consolidate ArtCompileMethods
Ian Rogers1212a022013-03-04 10:48:41 -0800144 CompileOneMethod(*compiler_driver_,
Ian Rogersc928de92013-02-27 14:30:44 -0800145 kPortable,
Ian Rogers89756f22013-03-04 16:40:02 -0800146 dex_compilation_unit->GetCodeItem(),
147 dex_compilation_unit->GetAccessFlags(),
Ian Rogersc928de92013-02-27 14:30:44 -0800148 invoke_type,
Ian Rogers89756f22013-03-04 16:40:02 -0800149 dex_compilation_unit->GetClassDefIndex(),
150 dex_compilation_unit->GetDexMethodIndex(),
151 dex_compilation_unit->GetClassLoader(),
152 *dex_compilation_unit->GetDexFile(),
Brian Carlstrom265091e2013-01-30 14:08:26 -0800153 cunit.get());
buzbee26f10ee2012-12-21 11:16:29 -0800154
Ian Rogersc928de92013-02-27 14:30:44 -0800155 cunit->Materialize();
Shih-wei Liaobb33f2f2012-08-23 13:20:00 -0700156
Ian Rogers89756f22013-03-04 16:40:02 -0800157 CompilerDriver::MethodReference mref(dex_compilation_unit->GetDexFile(),
158 dex_compilation_unit->GetDexMethodIndex());
Ian Rogers1212a022013-03-04 10:48:41 -0800159 return new CompiledMethod(compiler_driver_->GetInstructionSet(),
Brian Carlstrom265091e2013-01-30 14:08:26 -0800160 cunit->GetElfObject(),
161 *verifier::MethodVerifier::GetDexGcMap(mref),
162 cunit->GetDexCompilationUnit()->GetSymbol());
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800163}
Logan Chien83426162011-12-09 09:29:50 +0800164
165
Logan Chien7f767612012-03-01 18:54:49 +0800166CompiledMethod* CompilerLLVM::
Ian Rogers89756f22013-03-04 16:40:02 -0800167CompileNativeMethod(DexCompilationUnit* dex_compilation_unit) {
Brian Carlstrom641ce032013-01-31 15:21:37 -0800168 UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());
Logan Chien8ba2fc52012-04-23 09:10:46 +0800169
Logan Chien8b977d32012-02-21 19:14:55 +0800170 UniquePtr<JniCompiler> jni_compiler(
Ian Rogers89756f22013-03-04 16:40:02 -0800171 new JniCompiler(cunit.get(), *compiler_driver_, dex_compilation_unit));
Logan Chien8b977d32012-02-21 19:14:55 +0800172
Logan Chien7f767612012-03-01 18:54:49 +0800173 return jni_compiler->Compile();
Logan Chien88894ee2012-02-13 16:42:22 +0800174}
175
176
Logan Chienf04364f2012-02-10 12:01:39 +0800177CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
178 char const *shorty) {
Brian Carlstrom641ce032013-01-31 15:21:37 -0800179 UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());
Logan Chien8ba2fc52012-04-23 09:10:46 +0800180
TDYa127eead4ac2012-06-03 07:15:25 -0700181 UniquePtr<StubCompiler> stub_compiler(
Ian Rogers1212a022013-03-04 10:48:41 -0800182 new StubCompiler(cunit.get(), *compiler_driver_));
Logan Chien8b977d32012-02-21 19:14:55 +0800183
Logan Chien7a2a23a2012-06-06 11:01:00 +0800184 return stub_compiler->CreateInvokeStub(is_static, shorty);
185}
TDYa127eead4ac2012-06-03 07:15:25 -0700186
TDYa127eead4ac2012-06-03 07:15:25 -0700187
Logan Chien7a2a23a2012-06-06 11:01:00 +0800188CompiledInvokeStub* CompilerLLVM::CreateProxyStub(char const *shorty) {
Brian Carlstrom641ce032013-01-31 15:21:37 -0800189 UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());
Logan Chien7a2a23a2012-06-06 11:01:00 +0800190
191 UniquePtr<StubCompiler> stub_compiler(
Ian Rogers1212a022013-03-04 10:48:41 -0800192 new StubCompiler(cunit.get(), *compiler_driver_));
Logan Chien7a2a23a2012-06-06 11:01:00 +0800193
194 return stub_compiler->CreateProxyStub(shorty);
Logan Chienf04364f2012-02-10 12:01:39 +0800195}
196
Ian Rogers4c1c2832013-03-04 18:30:13 -0800197} // namespace llvm
Logan Chien83426162011-12-09 09:29:50 +0800198} // namespace art
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800199
Ian Rogers4c1c2832013-03-04 18:30:13 -0800200inline static art::llvm::CompilerLLVM* ContextOf(art::CompilerDriver& driver) {
Ian Rogers1212a022013-03-04 10:48:41 -0800201 void *compiler_context = driver.GetCompilerContext();
Logan Chien106b2a02012-03-18 04:41:38 +0800202 CHECK(compiler_context != NULL);
Ian Rogers4c1c2832013-03-04 18:30:13 -0800203 return reinterpret_cast<art::llvm::CompilerLLVM*>(compiler_context);
Logan Chien106b2a02012-03-18 04:41:38 +0800204}
205
Ian Rogers4c1c2832013-03-04 18:30:13 -0800206inline static const art::llvm::CompilerLLVM* ContextOf(const art::CompilerDriver& driver) {
Ian Rogers1212a022013-03-04 10:48:41 -0800207 void *compiler_context = driver.GetCompilerContext();
Logan Chien106b2a02012-03-18 04:41:38 +0800208 CHECK(compiler_context != NULL);
Ian Rogers4c1c2832013-03-04 18:30:13 -0800209 return reinterpret_cast<const art::llvm::CompilerLLVM*>(compiler_context);
Logan Chien106b2a02012-03-18 04:41:38 +0800210}
211
Ian Rogers1212a022013-03-04 10:48:41 -0800212extern "C" void ArtInitCompilerContext(art::CompilerDriver& driver) {
213 CHECK(driver.GetCompilerContext() == NULL);
Logan Chien106b2a02012-03-18 04:41:38 +0800214
Ian Rogers4c1c2832013-03-04 18:30:13 -0800215 art::llvm::CompilerLLVM* compiler_llvm = new art::llvm::CompilerLLVM(&driver,
216 driver.GetInstructionSet());
Logan Chien106b2a02012-03-18 04:41:38 +0800217
Ian Rogers1212a022013-03-04 10:48:41 -0800218 driver.SetCompilerContext(compiler_llvm);
Logan Chien106b2a02012-03-18 04:41:38 +0800219}
220
Ian Rogers1212a022013-03-04 10:48:41 -0800221extern "C" void ArtUnInitCompilerContext(art::CompilerDriver& driver) {
222 delete ContextOf(driver);
223 driver.SetCompilerContext(NULL);
Logan Chien971bf3f2012-05-01 15:47:55 +0800224}
Ian Rogers1212a022013-03-04 10:48:41 -0800225extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800226 const art::DexFile::CodeItem* code_item,
Ian Rogers08f753d2012-08-24 14:35:25 -0700227 uint32_t access_flags,
228 art::InvokeType invoke_type,
Ian Rogersfffdb022013-01-04 15:14:08 -0800229 uint32_t class_def_idx,
Ian Rogers08f753d2012-08-24 14:35:25 -0700230 uint32_t method_idx,
Shih-wei Liaocd05a622012-08-15 00:02:05 -0700231 jobject class_loader,
Ian Rogers08f753d2012-08-24 14:35:25 -0700232 const art::DexFile& dex_file) {
Ian Rogersfffdb022013-01-04 15:14:08 -0800233 UNUSED(class_def_idx); // TODO: this is used with Compiler::RequiresConstructorBarrier.
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800234 art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800235
Ian Rogers89756f22013-03-04 16:40:02 -0800236 art::DexCompilationUnit dex_compilation_unit(
Brian Carlstrom265091e2013-01-30 14:08:26 -0800237 NULL, class_loader, class_linker, dex_file, code_item,
TDYa127dc5daa02013-01-09 21:31:37 +0800238 class_def_idx, method_idx, access_flags);
Ian Rogers4c1c2832013-03-04 18:30:13 -0800239 art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver);
Ian Rogers89756f22013-03-04 16:40:02 -0800240 art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&dex_compilation_unit, invoke_type);
TDYa1270200d072012-04-17 20:55:08 -0700241 return result;
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800242}
243
Ian Rogers1212a022013-03-04 10:48:41 -0800244extern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::CompilerDriver& driver,
Brian Carlstrom00bc1dc2013-02-01 15:56:27 -0800245 uint32_t access_flags, uint32_t method_idx,
246 const art::DexFile& dex_file) {
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800247 art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800248
Ian Rogers89756f22013-03-04 16:40:02 -0800249 art::DexCompilationUnit dex_compilation_unit(
Brian Carlstrom265091e2013-01-30 14:08:26 -0800250 NULL, NULL, class_linker, dex_file, NULL,
TDYa127dc5daa02013-01-09 21:31:37 +0800251 0, method_idx, access_flags);
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800252
Ian Rogers4c1c2832013-03-04 18:30:13 -0800253 art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver);
Ian Rogers89756f22013-03-04 16:40:02 -0800254 art::CompiledMethod* result = compiler_llvm->CompileNativeMethod(&dex_compilation_unit);
Elliott Hughes13b835a2012-03-13 19:45:22 -0700255 return result;
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800256}
257
Ian Rogers1212a022013-03-04 10:48:41 -0800258extern "C" art::CompiledInvokeStub* ArtCreateLLVMInvokeStub(art::CompilerDriver& driver,
buzbee02031b12012-11-23 09:41:35 -0800259 bool is_static,
260 const char* shorty,
261 uint32_t shorty_len) {
Ian Rogers4c1c2832013-03-04 18:30:13 -0800262 art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver);
TDYa1270200d072012-04-17 20:55:08 -0700263 art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty);
TDYa1270200d072012-04-17 20:55:08 -0700264 return result;
Logan Chien106b2a02012-03-18 04:41:38 +0800265}
266
Ian Rogers1212a022013-03-04 10:48:41 -0800267extern "C" art::CompiledInvokeStub* ArtCreateProxyStub(art::CompilerDriver& driver,
Logan Chien7a2a23a2012-06-06 11:01:00 +0800268 const char* shorty,
269 uint32_t shorty_len) {
Ian Rogers4c1c2832013-03-04 18:30:13 -0800270 art::llvm::CompilerLLVM* compiler_llvm = ContextOf(driver);
Logan Chien7a2a23a2012-06-06 11:01:00 +0800271 art::CompiledInvokeStub* result = compiler_llvm->CreateProxyStub(shorty);
Logan Chien7a2a23a2012-06-06 11:01:00 +0800272 return result;
273}
274
Ian Rogers1212a022013-03-04 10:48:41 -0800275extern "C" void compilerLLVMSetBitcodeFileName(art::CompilerDriver& driver,
Logan Chien106b2a02012-03-18 04:41:38 +0800276 std::string const& filename) {
Ian Rogers1212a022013-03-04 10:48:41 -0800277 ContextOf(driver)->SetBitcodeFileName(filename);
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800278}