Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 1 | /* |
| 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 "greenland.h" |
| 18 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 19 | #include "gbc_context.h" |
| 20 | #include "gbc_function.h" |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 21 | #include "target_codegen_machine.h" |
| 22 | #include "target_registry.h" |
| 23 | |
| 24 | #include "class_linker.h" |
| 25 | #include "compiler.h" |
| 26 | #include "oat_compilation_unit.h" |
| 27 | #include "stl_util.h" |
| 28 | #include "utils.h" |
| 29 | |
| 30 | #include <vector> |
| 31 | |
| 32 | #include <llvm/InitializePasses.h> |
| 33 | #include <llvm/Module.h> |
| 34 | #include <llvm/PassRegistry.h> |
| 35 | #include <llvm/Support/Threading.h> |
| 36 | |
| 37 | namespace art { |
| 38 | namespace greenland { |
| 39 | |
| 40 | // Forward declarations |
| 41 | #define LLVM_TARGET(TargetName) void Initialize##TargetName##CodeGenMachine(); |
| 42 | #include <llvm/Config/Targets.def> |
| 43 | |
| 44 | #define LLVM_TARGET(TargetName) \ |
| 45 | void Initialize##TargetName##InvokeStubCompiler(); |
| 46 | #include <llvm/Config/Targets.def> |
| 47 | |
| 48 | } // namespace greeland |
| 49 | } // namespace art |
| 50 | |
| 51 | namespace { |
| 52 | |
| 53 | pthread_once_t greenland_initialized = PTHREAD_ONCE_INIT; |
| 54 | |
| 55 | void InitializeAllCodeGenMachines() { |
| 56 | #define LLVM_TARGET(TargetName) \ |
| 57 | art::greenland::Initialize##TargetName##CodeGenMachine(); |
| 58 | #include <llvm/Config/Targets.def> |
| 59 | } |
| 60 | |
| 61 | void InitializeAllInvokeStubCompilers() { |
| 62 | #define LLVM_TARGET(TargetName) \ |
| 63 | art::greenland::Initialize##TargetName##InvokeStubCompiler(); |
| 64 | #include <llvm/Config/Targets.def> |
| 65 | } |
| 66 | |
| 67 | void InitializeGreenland() { |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 68 | // Initialize LLVM internal data structure for multithreading |
| 69 | llvm::llvm_start_multithreaded(); |
| 70 | |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 71 | // Initialize passes |
| 72 | llvm::PassRegistry ®istry = *llvm::PassRegistry::getPassRegistry(); |
| 73 | |
| 74 | llvm::initializeCore(registry); |
| 75 | llvm::initializeScalarOpts(registry); |
| 76 | |
| 77 | // Run vectorization passes when our backend supports vector type |
| 78 | //llvm::initializeVectorization(registry); |
| 79 | |
| 80 | // DexLang operates on an llvm::Function and never runs IPO and IPA |
| 81 | //llvm::initializeIPO(registry); |
| 82 | //llvm::initializeIPA(registry); |
| 83 | |
| 84 | llvm::initializeAnalysis(registry); |
| 85 | llvm::initializeTransformUtils(registry); |
| 86 | llvm::initializeInstCombine(registry); |
| 87 | |
| 88 | InitializeAllCodeGenMachines(); |
| 89 | InitializeAllInvokeStubCompilers(); |
| 90 | |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 91 | return; |
| 92 | } |
| 93 | |
| 94 | } // anonymous namespace |
| 95 | |
| 96 | namespace art { |
| 97 | namespace greenland { |
| 98 | |
| 99 | Greenland::Greenland(art::Compiler& compiler) |
| 100 | : compiler_(compiler), codegen_machine_(NULL), |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 101 | lock_("greenland_compiler_lock"), cur_gbc_ctx_(NULL) { |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 102 | // Initialize Greenland |
| 103 | pthread_once(&greenland_initialized, InitializeGreenland); |
| 104 | |
| 105 | codegen_machine_ = |
| 106 | TargetCodeGenMachine::Create(compiler_.GetInstructionSet()); |
| 107 | DCHECK(codegen_machine_ != NULL); |
| 108 | return; |
| 109 | } |
| 110 | |
| 111 | Greenland::~Greenland() { |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 112 | cur_gbc_ctx_->DecRef(); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 113 | delete codegen_machine_; |
| 114 | } |
| 115 | |
| 116 | CompiledMethod* Greenland::Compile(OatCompilationUnit& cunit) { |
| 117 | MutexLock GUARD(lock_); |
| 118 | |
| 119 | // Dex to LLVM IR |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 120 | GBCContext& gbc_ctx = GetGBCContext(); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 121 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 122 | UniquePtr<DexLang> dex_lang(new DexLang(gbc_ctx.GetDexLangContext(), |
| 123 | compiler_, cunit)); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 124 | |
| 125 | llvm::Function* func = dex_lang->Build(); |
| 126 | |
| 127 | if (func == NULL) { |
| 128 | LOG(FATAL) << "Failed to run dexlang on " |
| 129 | << PrettyMethod(cunit.GetDexMethodIndex(), *cunit.GetDexFile()); |
| 130 | return NULL; |
| 131 | } |
| 132 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 133 | func->dump(); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 134 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 135 | // NOTE: From statistic, the bitcode size is 4.5 times bigger than the |
| 136 | // Dex file. Besides, we have to convert the code unit into bytes. |
| 137 | // Thus, we got our magic number 9. |
| 138 | gbc_ctx.AddMemUsageApproximation( |
| 139 | cunit.GetCodeItem()->insns_size_in_code_units_ * 900); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 140 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 141 | GBCFunction gbc_func(gbc_ctx, *func, cunit); |
| 142 | |
| 143 | UniquePtr<CompiledMethod> result(codegen_machine_->Run(compiler_, gbc_func)); |
| 144 | |
| 145 | // gbc_ctx was no longer needed |
| 146 | gbc_ctx.DecRef(); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 147 | |
| 148 | return result.release(); |
| 149 | } |
| 150 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 151 | GBCContext& Greenland::GetGBCContext() { |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 152 | //MutexLock GUARD(lock_); |
| 153 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 154 | ResetGBCContextIfThresholdReached(); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 155 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 156 | if (cur_gbc_ctx_ == NULL) { |
| 157 | cur_gbc_ctx_ = new GBCContext(); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 158 | } |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 159 | CHECK(cur_gbc_ctx_ != NULL); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 160 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 161 | return cur_gbc_ctx_->IncRef(); |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 162 | } |
| 163 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 164 | void Greenland::ResetGBCContextIfThresholdReached() { |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 165 | lock_.AssertHeld(); |
| 166 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 167 | if (cur_gbc_ctx_ == NULL) { |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 168 | return; |
| 169 | } |
| 170 | |
Shih-wei Liao | 21d28f5 | 2012-06-12 05:55:00 -0700 | [diff] [blame] | 171 | if (cur_gbc_ctx_->IsMemUsageThresholdReached()) { |
| 172 | cur_gbc_ctx_->DecRef(); |
| 173 | cur_gbc_ctx_ = NULL; |
Shih-wei Liao | e94d9b2 | 2012-05-22 09:01:24 -0700 | [diff] [blame] | 174 | } |
| 175 | return; |
| 176 | } |
| 177 | |
| 178 | } // namespace greenland |
| 179 | } // namespace art |
| 180 | |
| 181 | inline static art::greenland::Greenland* ContextOf(art::Compiler& compiler) { |
| 182 | void *compiler_context = compiler.GetCompilerContext(); |
| 183 | CHECK(compiler_context != NULL); |
| 184 | return reinterpret_cast<art::greenland::Greenland*>(compiler_context); |
| 185 | } |
| 186 | |
| 187 | extern "C" void ArtInitCompilerContext(art::Compiler& compiler) { |
| 188 | CHECK(compiler.GetCompilerContext() == NULL); |
| 189 | compiler.SetCompilerContext(new art::greenland::Greenland(compiler)); |
| 190 | return; |
| 191 | } |
| 192 | |
| 193 | extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler, |
| 194 | const art::DexFile::CodeItem* code_item, |
| 195 | uint32_t access_flags, uint32_t method_idx, |
| 196 | const art::ClassLoader* class_loader, |
| 197 | const art::DexFile& dex_file) |
| 198 | { |
| 199 | art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker(); |
| 200 | art::DexCache *dex_cache = class_linker->FindDexCache(dex_file); |
| 201 | |
| 202 | art::OatCompilationUnit cunit( |
| 203 | class_loader, class_linker, dex_file, *dex_cache, code_item, |
| 204 | method_idx, access_flags); |
| 205 | |
| 206 | return ContextOf(compiler)->Compile(cunit); |
| 207 | } |
| 208 | |
| 209 | extern "C" art::CompiledInvokeStub* ArtCreateInvokeStub(art::Compiler& compiler, |
| 210 | bool is_static, |
| 211 | const char* shorty, |
| 212 | uint32_t shorty_len) { |
| 213 | art::greenland::TargetRegistry::CreateInvokeStubFn compiler_fn = |
| 214 | art::greenland::TargetRegistry::GetInvokeStubCompiler(compiler.GetInstructionSet()); |
| 215 | CHECK(compiler_fn != NULL); |
| 216 | return (*compiler_fn)(compiler, is_static, shorty, shorty_len); |
| 217 | } |