| /* |
| * Copyright (C) 2012 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "compiler_llvm.h" |
| |
| #include "compiler.h" |
| #include "ir_builder.h" |
| #include "method_compiler.h" |
| #include "upcall_compiler.h" |
| |
| #include <llvm/ADT/OwningPtr.h> |
| #include <llvm/Bitcode/ReaderWriter.h> |
| #include <llvm/DerivedTypes.h> |
| #include <llvm/LLVMContext.h> |
| #include <llvm/Module.h> |
| #include <llvm/Support/ToolOutputFile.h> |
| |
| namespace art { |
| namespace compiler_llvm { |
| |
| |
| namespace { |
| using namespace llvm; |
| #include "art_module.cc" |
| } |
| |
| |
| CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set) |
| : compiler_(compiler), compiler_lock_("llvm_compiler_lock"), |
| insn_set_(insn_set), context_(new llvm::LLVMContext()) { |
| |
| // Create the module and include the runtime function declaration |
| module_ = new llvm::Module("art", *context_); |
| makeLLVMModuleContents(module_); |
| |
| // Create IRBuilder |
| irb_.reset(new IRBuilder(*context_, *module_)); |
| } |
| |
| |
| CompilerLLVM::~CompilerLLVM() { |
| } |
| |
| |
| void CompilerLLVM::MaterializeLLVMModule() { |
| #if !defined(NDEBUG) |
| // TODO: Add options to JNI_CreateJavaVM() and dex2oat, so that we don't |
| // have to hard-code the path. |
| WriteBitcodeToFile("/tmp/art_llvm_module.bc"); |
| #endif |
| } |
| |
| |
| void CompilerLLVM::WriteBitcodeToFile(std::string const &filepath) { |
| std::string error_msg; |
| |
| // Write the translated bitcode |
| llvm::OwningPtr<llvm::tool_output_file> |
| out(new llvm::tool_output_file(filepath.c_str(), error_msg, |
| llvm::raw_fd_ostream::F_Binary)); |
| |
| if (!error_msg.empty()) { |
| LOG(FATAL) << "Unable to open file: " << error_msg; |
| return; |
| } |
| |
| llvm::WriteBitcodeToFile(module_, out->os()); |
| out->keep(); |
| |
| LOG(DEBUG) << "Bitcode Written At: " << filepath; |
| } |
| |
| |
| CompiledMethod* |
| CompilerLLVM::CompileDexMethod(DexFile::CodeItem const* code_item, |
| uint32_t access_flags, |
| uint32_t method_idx, |
| ClassLoader const* class_loader, |
| DexFile const& dex_file) { |
| |
| MutexLock GUARD(compiler_lock_); |
| |
| ClassLinker *class_linker = Runtime::Current()->GetClassLinker(); |
| DexCache *dex_cache = class_linker->FindDexCache(dex_file); |
| |
| UniquePtr<MethodCompiler> method_compiler( |
| new MethodCompiler(insn_set_, compiler_, class_linker, class_loader, |
| &dex_file, dex_cache, code_item, method_idx, |
| access_flags)); |
| |
| return method_compiler->Compile(); |
| } |
| |
| |
| CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static, |
| char const *shorty) { |
| |
| MutexLock GUARD(compiler_lock_); |
| |
| UniquePtr<UpcallCompiler> upcall_compiler( |
| new UpcallCompiler(insn_set_, *compiler_)); |
| |
| return upcall_compiler->CreateStub(is_static, shorty); |
| } |
| |
| |
| } // namespace compiler_llvm |
| } // namespace art |