Quick compiler: reuse llvm context & ir builder
With this CL, we avoid setting up an llvm context, module and intrinsic
definitions for each method, and considerably speed up compilation time.
This does not represent a final form - we'll be reworking the compiler driver
to support Quick & Portable via the command line, and this code will likely
change at that time.
Change-Id: I19e298a011141c3bc35c4f28175b2b20653fd5e4
diff --git a/src/compiler.cc b/src/compiler.cc
index 091aad9..b05e688 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -331,6 +331,16 @@
"ArtInitCompilerContext");
init_compiler_context(*this);
+#elif defined(ART_USE_QUICK_COMPILER)
+ // Initialize compiler_context_
+ typedef void (*InitCompilerContextFn)(Compiler&);
+
+ InitCompilerContextFn init_compiler_context =
+ FindFunction<void (*)(Compiler&)>(compiler_so_name,
+ compiler_library_,
+ "ArtInitQuickCompilerContext");
+
+ init_compiler_context(*this);
#endif
compiler_ = FindFunction<CompilerFn>(compiler_so_name, compiler_library_, "ArtCompileMethod");
@@ -387,6 +397,18 @@
"ArtUnInitCompilerContext");
uninit_compiler_context(*this);
+#elif defined(ART_USE_QUICK_COMPILER)
+ // Uninitialize compiler_context_
+ typedef void (*UninitCompilerContextFn)(Compiler&);
+
+ std::string compiler_so_name(MakeCompilerSoName(instruction_set_));
+
+ UninitCompilerContextFn uninit_compiler_context =
+ FindFunction<void (*)(Compiler&)>(compiler_so_name,
+ compiler_library_,
+ "ArtUnInitQuickCompilerContext");
+
+ uninit_compiler_context(*this);
#endif
if (compiler_library_ != NULL) {
VLOG(compiler) << "dlclose(" << compiler_library_ << ")";
diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h
index 659b5a6..9ac6016 100644
--- a/src/compiler/Compiler.h
+++ b/src/compiler/Compiler.h
@@ -20,7 +20,20 @@
#include "dex_file.h"
#include "dex_instruction.h"
+#if defined(ART_USE_QUICK_COMPILER)
+namespace llvm {
+ class Module;
+ class LLVMContext;
+}
+#endif
+
namespace art {
+#if defined(ART_USE_QUICK_COMPILER)
+namespace greenland {
+ class IntrinsicHelper;
+ class IRBuilder;
+}
+#endif
#define COMPILER_TRACED(X)
#define COMPILER_TRACEE(X)
@@ -163,6 +176,41 @@
kReversePostOrderTraversal, // Depth-First-Search / reverse Post-Order
};
+#if defined(ART_USE_QUICK_COMPILER)
+class QuickCompiler {
+ public:
+ QuickCompiler(art::Compiler* compiler);
+ ~QuickCompiler();
+
+ const art::Compiler* GetCompiler() const {
+ return compiler_;
+ }
+
+ llvm::LLVMContext* GetLLVMContext() {
+ return llvm_context_.get();
+ }
+
+ llvm::Module* GetLLVMModule() {
+ return llvm_module_.get();
+ }
+
+ art::greenland::IntrinsicHelper* GetIntrinsicHelper() {
+ return intrinsic_helper_.get();
+ }
+
+ art::greenland::IRBuilder* GetIRBuilder() {
+ return ir_builder_.get();
+ }
+
+ private:
+ const art::Compiler* const compiler_;
+ UniquePtr<llvm::LLVMContext> llvm_context_;
+ UniquePtr<llvm::Module> llvm_module_;
+ UniquePtr<art::greenland::IntrinsicHelper> intrinsic_helper_;
+ UniquePtr<art::greenland::IRBuilder> ir_builder_;
+};
+#endif
+
struct CompilationUnit;
struct BasicBlock;
struct SSARepresentation;
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 3c579c4..8c403c5 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -23,6 +23,34 @@
namespace art {
+#if defined(ART_USE_QUICK_COMPILER)
+QuickCompiler::QuickCompiler(art::Compiler* compiler)
+ : compiler_(compiler) {
+ // Create context, module, intrinsic helper & ir builder
+ llvm_context_.reset(new llvm::LLVMContext());
+ llvm_module_.reset(new llvm::Module("art", *llvm_context_));
+ llvm::StructType::create(*llvm_context_, "JavaObject");
+ llvm::StructType::create(*llvm_context_, "Method");
+ llvm::StructType::create(*llvm_context_, "Thread");
+ intrinsic_helper_.reset( new greenland::IntrinsicHelper(*llvm_context_, *llvm_module_));
+ ir_builder_.reset(new greenland::IRBuilder(*llvm_context_, *llvm_module_, *intrinsic_helper_));
+}
+
+QuickCompiler::~QuickCompiler() {
+}
+
+extern "C" void ArtInitQuickCompilerContext(art::Compiler& compiler) {
+ CHECK(compiler.GetCompilerContext() == NULL);
+ QuickCompiler* quickCompiler = new QuickCompiler(&compiler);
+ compiler.SetCompilerContext(quickCompiler);
+}
+
+extern "C" void ArtUnInitQuickCompilerContext(art::Compiler& compiler) {
+ delete reinterpret_cast<QuickCompiler*>(compiler.GetCompilerContext());
+ compiler.SetCompilerContext(NULL);
+}
+#endif
+
/* Default optimizer/debug setting for the compiler. */
static uint32_t kCompilerOptimizerDisableFlags = 0 | // Disable specific optimizations
//(1 << kLoadStoreElimination) |
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index c84d6d3..cfe6e6a 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -166,27 +166,14 @@
}
cUnit->locMap.Put(val, loc);
}
-
void initIR(CompilationUnit* cUnit)
{
- cUnit->context = new llvm::LLVMContext();
- cUnit->module = new llvm::Module("art", *cUnit->context);
- llvm::StructType::create(*cUnit->context, "JavaObject");
- llvm::StructType::create(*cUnit->context, "Method");
- llvm::StructType::create(*cUnit->context, "Thread");
- cUnit->intrinsic_helper =
- new greenland::IntrinsicHelper(*cUnit->context, *cUnit->module);
- cUnit->irb =
- new greenland::IRBuilder(*cUnit->context, *cUnit->module,
- *cUnit->intrinsic_helper);
-}
-
-void freeIR(CompilationUnit* cUnit)
-{
- delete cUnit->irb;
- delete cUnit->intrinsic_helper;
- delete cUnit->module;
- delete cUnit->context;
+ QuickCompiler* quick =
+ reinterpret_cast<QuickCompiler*>(cUnit->compiler->GetCompilerContext());
+ cUnit->context = quick->GetLLVMContext();
+ cUnit->module = quick->GetLLVMModule();
+ cUnit->intrinsic_helper = quick->GetIntrinsicHelper();
+ cUnit->irb = quick->GetIRBuilder();
}
const char* llvmSSAName(CompilationUnit* cUnit, int ssaReg) {
@@ -840,7 +827,6 @@
RegLocation rlSrc[3];
RegLocation rlDest = badLoc;
Instruction::Code opcode = mir->dalvikInsn.opcode;
- uint32_t vA = mir->dalvikInsn.vA;
uint32_t vB = mir->dalvikInsn.vB;
uint32_t vC = mir->dalvikInsn.vC;
int optFlags = mir->optimizationFlags;
@@ -3480,7 +3466,8 @@
handleIntrinsicLaunchpads(cUnit);
- freeIR(cUnit);
+ cUnit->func->eraseFromParent();
+ cUnit->func = NULL;
}