diff options
| author | 2012-02-21 19:14:55 +0800 | |
|---|---|---|
| committer | 2012-02-29 17:11:27 -0800 | |
| commit | 8b977d38483aaa08abcbdaa5fa888076c1142169 (patch) | |
| tree | ae61c7cb1c397582f22c5c585bb0b531fd8f59b0 /src/compiler_llvm/compiler_llvm.cc | |
| parent | 88894ee835411de72025cd8a5d8d111a6f2a004a (diff) | |
Compile llvm.Module into ELF object file.
Change-Id: I8faf7427944324c9bac12573d217cde2a2e658f1
Diffstat (limited to 'src/compiler_llvm/compiler_llvm.cc')
| -rw-r--r-- | src/compiler_llvm/compiler_llvm.cc | 123 |
1 files changed, 86 insertions, 37 deletions
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc index 1489ec472d..56f0b07418 100644 --- a/src/compiler_llvm/compiler_llvm.cc +++ b/src/compiler_llvm/compiler_llvm.cc @@ -16,6 +16,7 @@ #include "compiler_llvm.h" +#include "compilation_unit.h" #include "compiler.h" #include "ir_builder.h" #include "jni_compiler.h" @@ -23,12 +24,28 @@ #include "oat_compilation_unit.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> +#include <llvm/Support/TargetSelect.h> +#include <llvm/Support/Threading.h> + + +namespace { + +pthread_once_t llvm_initialized = PTHREAD_ONCE_INIT; + +void InitializeLLVM() { + // Initialize LLVM target, MC subsystem, asm printer, and asm parser + llvm::InitializeAllTargets(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmPrinters(); + llvm::InitializeAllAsmParsers(); + // TODO: Maybe we don't have to initialize "all" targets. + + // Initialize LLVM internal data structure for multithreading + llvm::llvm_start_multithreaded(); +} + +} // anonymous namespace + namespace art { namespace compiler_llvm { @@ -39,67 +56,93 @@ llvm::Module* makeLLVMModuleContents(llvm::Module* module); CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set) : compiler_(compiler), compiler_lock_("llvm_compiler_lock"), - insn_set_(insn_set), context_(new llvm::LLVMContext()) { + insn_set_(insn_set), cunit_counter_(0) { - // 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_)); + // Initialize LLVM libraries + pthread_once(&llvm_initialized, InitializeLLVM); } CompilerLLVM::~CompilerLLVM() { + DCHECK(cunit_.get() == NULL); } -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::EnsureCompilationUnit() { + DCHECK_NE(llvm_initialized, PTHREAD_ONCE_INIT); + if (cunit_.get() == NULL) { + cunit_.reset(new CompilationUnit(insn_set_)); + } } -void CompilerLLVM::WriteBitcodeToFile(std::string const &filepath) { - std::string error_msg; +void CompilerLLVM::MaterializeEveryCompilationUnit() { + if (cunit_.get() != NULL) { + MaterializeCompilationUnit(); + } +} - // 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; +void CompilerLLVM::MaterializeCompilationUnitSafePoint() { + if (cunit_->IsMaterializeThresholdReached()) { + MaterializeCompilationUnit(); } +} + - llvm::WriteBitcodeToFile(module_, out->os()); - out->keep(); +void CompilerLLVM::MaterializeCompilationUnit() { + MutexLock GUARD(compiler_lock_); - LOG(DEBUG) << "Bitcode Written At: " << filepath; + cunit_->SetElfFileName(StringPrintf("%s-%u", elf_filename_.c_str(), + cunit_counter_)); + + // Write the translated bitcode for debugging + if (!bitcode_filename_.empty()) { + cunit_->SetBitcodeFileName(StringPrintf("%s-%u", bitcode_filename_.c_str(), + cunit_counter_)); + cunit_->WriteBitcodeToFile(); + } + + // Materialize the llvm::Module into ELF object file + cunit_->Materialize(); + + // Increase compilation unit counter + ++cunit_counter_; + + // Delete the compilation unit + cunit_.reset(NULL); } CompiledMethod* CompilerLLVM::CompileDexMethod(OatCompilationUnit* oat_compilation_unit) { MutexLock GUARD(compiler_lock_); + EnsureCompilationUnit(); + UniquePtr<MethodCompiler> method_compiler( - new MethodCompiler(insn_set_, compiler_, oat_compilation_unit)); + new MethodCompiler(cunit_.get(), compiler_, oat_compilation_unit)); + + CompiledMethod* result = method_compiler->Compile(); - return method_compiler->Compile(); + MaterializeCompilationUnitSafePoint(); + + return result; } CompiledMethod* CompilerLLVM::CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) { MutexLock GUARD(compiler_lock_); + EnsureCompilationUnit(); + UniquePtr<JniCompiler> jni_compiler( - new JniCompiler(insn_set_, *compiler_, oat_compilation_unit)); + new JniCompiler(cunit_.get(), *compiler_, oat_compilation_unit)); + + CompiledMethod* result = jni_compiler->Compile(); + + MaterializeCompilationUnitSafePoint(); - return jni_compiler->Compile(); + return result; } @@ -108,10 +151,16 @@ CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static, MutexLock GUARD(compiler_lock_); + EnsureCompilationUnit(); + UniquePtr<UpcallCompiler> upcall_compiler( - new UpcallCompiler(insn_set_, *compiler_)); + new UpcallCompiler(cunit_.get(), *compiler_)); + + CompiledInvokeStub* result = upcall_compiler->CreateStub(is_static, shorty); + + MaterializeCompilationUnitSafePoint(); - return upcall_compiler->CreateStub(is_static, shorty); + return result; } |