Cleanup LLVM code generation code.
Materialize the bitcode in the end of CompileClass,
so that the code generation time won't be calculated
in method compilation time.
Change-Id: I1e2bd0b23bcb5c55bd966a31b1df0b8b34922f94
diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc
index 08c3dfc..ac956ef 100644
--- a/src/compiler_llvm/compilation_unit.cc
+++ b/src/compiler_llvm/compilation_unit.cc
@@ -193,24 +193,22 @@
fpm.run(*F);
}
fpm.doFinalization();
- LOG(INFO) << "Intraprocedural optimization finished!";
// Run the code generation passes
pm.run(*module_);
- LOG(INFO) << "Code generation finished!";
+ // Keep the generated executable
out_file->keep();
- LOG(DEBUG) << "ELF: " << elf_filename_ << " (done)";
+ LOG(INFO) << "ELF: " << elf_filename_ << " (done)";
+
+ // Free the resources
+ context_.reset(NULL);
+ irb_.reset(NULL);
+ module_ = NULL;
return true;
}
-void CompilationUnit::Finalize() {
- context_.reset(NULL);
- irb_.reset(NULL);
- module_ = NULL;
-}
-
} // namespace compiler_llvm
} // namespace art
diff --git a/src/compiler_llvm/compilation_unit.h b/src/compiler_llvm/compilation_unit.h
index a10d977..2ae5c0b 100644
--- a/src/compiler_llvm/compilation_unit.h
+++ b/src/compiler_llvm/compilation_unit.h
@@ -56,12 +56,10 @@
}
std::string const& GetElfFileName() const {
- CHECK(IsFinalized());
return elf_filename_;
}
std::string const& GetBitcodeFileName() const {
- CHECK(IsFinalized());
return bitcode_filename_;
}
@@ -77,12 +75,10 @@
bool Materialize();
- bool IsFinalized() const {
+ bool IsMaterialized() const {
return (context_.get() == NULL);
}
- void Finalize();
-
bool IsMaterializeThresholdReached() const {
return (mem_usage_ > 300000000u); // (threshold: 300 MB)
}
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 146f577..345872e 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -22,6 +22,7 @@
#include "jni_compiler.h"
#include "method_compiler.h"
#include "oat_compilation_unit.h"
+#include "stl_util.h"
#include "upcall_compiler.h"
#include <llvm/LinkAllPasses.h>
@@ -71,7 +72,7 @@
CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
: compiler_(compiler), compiler_lock_("llvm_compiler_lock"),
- insn_set_(insn_set), cunit_counter_(0) {
+ insn_set_(insn_set), curr_cunit_(NULL) {
// Initialize LLVM libraries
pthread_once(&llvm_initialized, InitializeLLVM);
@@ -79,104 +80,105 @@
CompilerLLVM::~CompilerLLVM() {
- DCHECK(cunit_.get() == NULL);
+ STLDeleteElements(&cunits_);
}
-void CompilerLLVM::EnsureCompilationUnit() {
- MutexLock GUARD(compiler_lock_);
+void CompilerLLVM::EnsureCompilationUnit(MutexLock& GUARD) {
DCHECK_NE(llvm_initialized, PTHREAD_ONCE_INIT);
- if (cunit_.get() == NULL) {
- cunit_.reset(new CompilationUnit(insn_set_));
+
+ if (curr_cunit_ != NULL) {
+ return;
}
+
+ // Allocate compilation unit
+ size_t cunit_idx = cunits_.size();
+
+ curr_cunit_ = new CompilationUnit(insn_set_);
+
+ // Setup output filename
+ curr_cunit_->SetElfFileName(
+ StringPrintf("%s-%zu", elf_filename_.c_str(), cunit_idx));
+
+ if (IsBitcodeFileNameAvailable()) {
+ curr_cunit_->SetBitcodeFileName(
+ StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit_idx));
+ }
+
+ // Register compilation unit
+ cunits_.push_back(curr_cunit_);
}
-void CompilerLLVM::MaterializeEveryCompilationUnit() {
- if (cunit_.get() != NULL) {
- MaterializeCompilationUnit();
- }
-}
-
-
-void CompilerLLVM::MaterializeCompilationUnitSafePoint() {
- if (cunit_->IsMaterializeThresholdReached()) {
- MaterializeCompilationUnit();
- }
-}
-
-
-void CompilerLLVM::MaterializeCompilationUnit() {
+void CompilerLLVM::MaterializeRemainder() {
MutexLock GUARD(compiler_lock_);
+ if (curr_cunit_ != NULL) {
+ Materialize(GUARD);
+ }
+}
- 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();
+void CompilerLLVM::MaterializeIfThresholdReached() {
+ MutexLock GUARD(compiler_lock_);
+ if (curr_cunit_ != NULL && curr_cunit_->IsMaterializeThresholdReached()) {
+ Materialize(GUARD);
+ }
+}
+
+
+void CompilerLLVM::Materialize(MutexLock& GUARD) {
+ DCHECK(curr_cunit_ != NULL);
+ DCHECK(!curr_cunit_->IsMaterialized());
+
+ // Write bitcode to file when filename is set
+ if (IsBitcodeFileNameAvailable()) {
+ curr_cunit_->WriteBitcodeToFile();
}
// Materialize the llvm::Module into ELF object file
- cunit_->Materialize();
-
- // Increase compilation unit counter
- ++cunit_counter_;
+ curr_cunit_->Materialize();
// Delete the compilation unit
- cunit_.reset(NULL);
+ curr_cunit_ = NULL;
}
-CompiledMethod* CompilerLLVM::CompileDexMethod(OatCompilationUnit* oat_compilation_unit) {
+CompiledMethod* CompilerLLVM::
+CompileDexMethod(OatCompilationUnit* oat_compilation_unit) {
MutexLock GUARD(compiler_lock_);
- EnsureCompilationUnit();
+ EnsureCompilationUnit(GUARD);
UniquePtr<MethodCompiler> method_compiler(
- new MethodCompiler(cunit_.get(), compiler_, oat_compilation_unit));
+ new MethodCompiler(curr_cunit_, compiler_, oat_compilation_unit));
- CompiledMethod* result = method_compiler->Compile();
-
- MaterializeCompilationUnitSafePoint();
-
- return result;
+ return method_compiler->Compile();
}
-CompiledMethod* CompilerLLVM::CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
+CompiledMethod* CompilerLLVM::
+CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
MutexLock GUARD(compiler_lock_);
- EnsureCompilationUnit();
+ EnsureCompilationUnit(GUARD);
UniquePtr<JniCompiler> jni_compiler(
- new JniCompiler(cunit_.get(), *compiler_, oat_compilation_unit));
+ new JniCompiler(curr_cunit_, *compiler_, oat_compilation_unit));
- CompiledMethod* result = jni_compiler->Compile();
-
- MaterializeCompilationUnitSafePoint();
-
- return result;
+ return jni_compiler->Compile();
}
CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
char const *shorty) {
-
MutexLock GUARD(compiler_lock_);
- EnsureCompilationUnit();
+ EnsureCompilationUnit(GUARD);
UniquePtr<UpcallCompiler> upcall_compiler(
- new UpcallCompiler(cunit_.get(), *compiler_));
+ new UpcallCompiler(curr_cunit_, *compiler_));
- CompiledInvokeStub* result = upcall_compiler->CreateStub(is_static, shorty);
-
- MaterializeCompilationUnitSafePoint();
-
- return result;
+ return upcall_compiler->CreateStub(is_static, shorty);
}
diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h
index 208edfc..3c653a3 100644
--- a/src/compiler_llvm/compiler_llvm.h
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -56,7 +56,9 @@
~CompilerLLVM();
- void MaterializeEveryCompilationUnit();
+ void MaterializeIfThresholdReached();
+
+ void MaterializeRemainder();
Compiler* GetCompiler() const {
return compiler_;
@@ -81,21 +83,25 @@
CompiledInvokeStub* CreateInvokeStub(bool is_static, char const *shorty);
private:
- void EnsureCompilationUnit();
+ void EnsureCompilationUnit(MutexLock& GUARD);
- void MaterializeCompilationUnit();
+ void Materialize(MutexLock& GUARD);
- void MaterializeCompilationUnitSafePoint();
+ bool IsBitcodeFileNameAvailable() const {
+ return !bitcode_filename_.empty();
+ }
Compiler* compiler_;
+ public:
Mutex compiler_lock_;
+ private:
InstructionSet insn_set_;
- UniquePtr<CompilationUnit> cunit_;
+ CompilationUnit* curr_cunit_;
- unsigned cunit_counter_;
+ std::vector<CompilationUnit*> cunits_;
std::string elf_filename_;