Get PORTABLE + SMALL on x86.
Implemented the portable resolution trampoline and
the portable to interpreter bridge.
Also work on integrating SEA_IR in the PORTABLE+SMALL framework.
Refactor some naming and correct indenting.
Change-Id: Ibd97da5e5b6f5148274c9bff368e3654b661ef51
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index b8727fe..4659f7b 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2231,13 +2231,18 @@
} else if ((access_flags & kAccAbstract) != 0) {
} else {
bool compile = verifier::MethodVerifier::IsCandidateForCompilation(code_item, access_flags);
+#ifdef ART_SEA_IR_MODE
+ bool use_sea = Runtime::Current()->IsSeaIRMode();
+ use_sea = use_sea && (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
+ if (use_sea) compile = true;
+#endif
+
if (compile) {
CompilerFn compiler = compiler_;
#ifdef ART_SEA_IR_MODE
- bool use_sea = Runtime::Current()->IsSeaIRMode();
- use_sea = use_sea && (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
if (use_sea) {
compiler = sea_ir_compiler_;
+ LOG(INFO) << "Using SEA IR to compile..." << std::endl;
}
#endif
// NOTE: if compiler declines to compile this method, it will return NULL.
diff --git a/compiler/sea_ir/debug/dot_gen.h b/compiler/sea_ir/debug/dot_gen.h
index 5270582..05d97fa 100644
--- a/compiler/sea_ir/debug/dot_gen.h
+++ b/compiler/sea_ir/debug/dot_gen.h
@@ -20,6 +20,7 @@
#include "safe_map.h"
#include "base/stringprintf.h"
#include "file_output_stream.h"
+#include "os.h"
#include "sea_ir/ir/sea.h"
#include "sea_ir/types/type_inference.h"
@@ -103,7 +104,7 @@
LOG(INFO) << "Starting to write SEA string to file.";
DotGenerationVisitor dgv = DotGenerationVisitor(&options_, types);
graph->Accept(&dgv);
- art::File* file = art::OS::OpenFile(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC);
+ art::File* file = art::OS::OpenFileReadWrite(filename.c_str());
art::FileOutputStream fos(file);
std::string graph_as_string = dgv.GetResult();
graph_as_string += "}";
diff --git a/compiler/sea_ir/frontend.cc b/compiler/sea_ir/frontend.cc
index e24d07d..421c3a4 100644
--- a/compiler/sea_ir/frontend.cc
+++ b/compiler/sea_ir/frontend.cc
@@ -16,18 +16,26 @@
#ifdef ART_SEA_IR_MODE
#include <llvm/Support/Threading.h>
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Bitcode/ReaderWriter.h>
+
#include "base/logging.h"
+#include "llvm/llvm_compilation_unit.h"
#include "dex/portable/mir_to_gbc.h"
#include "driver/compiler_driver.h"
-#include "leb128.h"
-#include "llvm/llvm_compilation_unit.h"
+#include "verifier/method_verifier.h"
#include "mirror/object.h"
+#include "utils.h"
+
#include "runtime.h"
#include "safe_map.h"
#include "sea_ir/ir/sea.h"
#include "sea_ir/debug/dot_gen.h"
#include "sea_ir/types/types.h"
+#include "sea_ir/code_gen/code_gen.h"
+
+
namespace art {
static CompiledMethod* CompileMethodWithSeaIr(CompilerDriver& compiler,
@@ -44,12 +52,31 @@
// and silencing the cpplint.py warning, I just corrected the formatting.
VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
sea_ir::SeaGraph* ir_graph = sea_ir::SeaGraph::GetGraph(dex_file);
- ir_graph->CompileMethod(code_item, class_def_idx, method_idx, method_access_flags, dex_file);
+ sea_ir::CodeGenData* llvm_data =
+ ir_graph->CompileMethod(code_item, class_def_idx, method_idx, method_access_flags, dex_file);
sea_ir::DotConversion dc;
SafeMap<int, const sea_ir::Type*>* types = ir_graph->ti_->GetTypeMap();
dc.DumpSea(ir_graph, "/tmp/temp.dot", types);
CHECK(0 && "No SEA compiled function exists yet.");
- return NULL;
+
+ MethodReference mref(&dex_file, method_idx);
+
+ // TODO: Passing the LLVM code as string is ugly and inefficient,
+ // but it is the way portable did it. I kept it for compatibility,
+ // but actually it should not happen.
+ std::string llvm_code;
+ ::llvm::raw_string_ostream str_os(llvm_code);
+ ::llvm::WriteBitcodeToFile(&llvm_data->module_, str_os);
+
+ std::string symbol = "dex_";
+ symbol += MangleForJni(PrettyMethod(method_idx, dex_file));
+
+ CompiledMethod* compiled_method = new CompiledMethod(
+ compiler.GetInstructionSet(),
+ llvm_code,
+ *verifier::MethodVerifier::GetDexGcMap(mref),
+ symbol);
+ return compiled_method;
}
CompiledMethod* SeaIrCompileOneMethod(CompilerDriver& compiler,
diff --git a/compiler/sea_ir/ir/sea.cc b/compiler/sea_ir/ir/sea.cc
index 08fe0e1..902839d 100644
--- a/compiler/sea_ir/ir/sea.cc
+++ b/compiler/sea_ir/ir/sea.cc
@@ -386,7 +386,7 @@
scoped_table->CloseScope();
}
-void SeaGraph::GenerateLLVM() {
+CodeGenData* SeaGraph::GenerateLLVM() {
// Pass: Generate LLVM IR.
CodeGenPrepassVisitor code_gen_prepass_visitor;
std::cout << "Generating code..." << std::endl;
@@ -399,9 +399,11 @@
CodeGenPostpassVisitor code_gen_postpass_visitor(code_gen_visitor.GetData());
Accept(&code_gen_postpass_visitor);
code_gen_postpass_visitor.Write(std::string("my_file.llvm"));
+ return code_gen_postpass_visitor.GetData();
}
-void SeaGraph::CompileMethod(const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
+CodeGenData* SeaGraph::CompileMethod(
+ const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file) {
// Two passes: Builds the intermediate structure (non-SSA) of the sea-ir for the function.
BuildMethodSeaGraph(code_item, dex_file, class_def_idx, method_idx, method_access_flags);
@@ -420,7 +422,8 @@
// Pass: type inference
ti_->ComputeTypes(this);
// Pass: Generate LLVM IR.
- GenerateLLVM();
+ CodeGenData* cgd = GenerateLLVM();
+ return cgd;
}
void SeaGraph::ComputeDominanceFrontier() {
diff --git a/compiler/sea_ir/ir/sea.h b/compiler/sea_ir/ir/sea.h
index 0b20ed7..df420ed 100644
--- a/compiler/sea_ir/ir/sea.h
+++ b/compiler/sea_ir/ir/sea.h
@@ -37,6 +37,7 @@
};
class TypeInference;
+class CodeGenData;
class Region;
class InstructionNode;
@@ -260,7 +261,7 @@
public:
static SeaGraph* GetGraph(const art::DexFile&);
- void CompileMethod(const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
+ CodeGenData* CompileMethod(const art::DexFile::CodeItem* code_item, uint32_t class_def_idx,
uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file);
// Returns all regions corresponding to this SeaGraph.
std::vector<Region*>* GetRegions() {
@@ -337,7 +338,7 @@
void RenameAsSSA(Region* node, utils::ScopedHashtable<int, InstructionNode*>* scoped_table);
// Generate LLVM IR for the method.
// Precondition: ConvertToSSA().
- void GenerateLLVM();
+ CodeGenData* GenerateLLVM();
static SeaGraph graph_;
std::vector<Region*> regions_;