blob: c88c38ed17a4e1113bce75e35a0e7d6fef5af834 [file] [log] [blame]
Nicolas Geoffrayb34f69a2014-03-07 15:28:39 +00001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "compiler.h"
18#include "compilers.h"
19#include "driver/compiler_driver.h"
20#include "mirror/art_method-inl.h"
21
22#ifdef ART_USE_PORTABLE_COMPILER
23#include "dex/portable/mir_to_gbc.h"
24#include "elf_writer_mclinker.h"
25#endif
26
27namespace art {
28
29#ifdef ART_SEA_IR_MODE
30extern "C" art::CompiledMethod* SeaIrCompileMethod(art::CompilerDriver& driver,
31 const art::DexFile::CodeItem* code_item,
32 uint32_t access_flags,
33 art::InvokeType invoke_type,
34 uint16_t class_def_idx,
35 uint32_t method_idx,
36 jobject class_loader,
37 const art::DexFile& dex_file);
38#endif
39
40
41CompiledMethod* Compiler::TryCompileWithSeaIR(art::CompilerDriver& driver,
42 const art::DexFile::CodeItem* code_item,
43 uint32_t access_flags,
44 art::InvokeType invoke_type,
45 uint16_t class_def_idx,
46 uint32_t method_idx,
47 jobject class_loader,
48 const art::DexFile& dex_file) {
49#ifdef ART_SEA_IR_MODE
50 bool use_sea = Runtime::Current()->IsSeaIRMode();
51 use_sea = use_sea &&
52 (std::string::npos != PrettyMethod(method_idx, dex_file).find("fibonacci"));
53 if (use_sea) {
54 LOG(INFO) << "Using SEA IR to compile..." << std::endl;
55 return SeaIrCompileMethod(compiler,
56 code_item,
57 access_flags,
58 invoke_type,
59 class_def_idx,
60 method_idx,
61 class_loader,
62 dex_file);
63 }
64#endif
65 return nullptr;
66}
67
68
69#ifdef ART_USE_PORTABLE_COMPILER
70
71extern "C" void ArtInitCompilerContext(art::CompilerDriver& driver);
72
73extern "C" void ArtUnInitCompilerContext(art::CompilerDriver& driver);
74
75extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver,
76 const art::DexFile::CodeItem* code_item,
77 uint32_t access_flags,
78 art::InvokeType invoke_type,
79 uint16_t class_def_idx,
80 uint32_t method_idx,
81 jobject class_loader,
82 const art::DexFile& dex_file);
83
84extern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::CompilerDriver& driver,
85 uint32_t access_flags, uint32_t method_idx,
86 const art::DexFile& dex_file);
87
88extern "C" void compilerLLVMSetBitcodeFileName(art::CompilerDriver& driver,
89 std::string const& filename);
90
91
92class LLVMCompiler : public Compiler {
93 public:
94 LLVMCompiler() : Compiler(1000) {}
95
96 void Init(CompilerDriver& driver) const {
97 ArtInitCompilerContext(driver);
98 }
99
100 void UnInit(CompilerDriver& driver) const {
101 ArtUnInitCompilerContext(driver);
102 }
103
104 CompiledMethod* Compile(CompilerDriver& driver,
105 const DexFile::CodeItem* code_item,
106 uint32_t access_flags,
107 InvokeType invoke_type,
108 uint16_t class_def_idx,
109 uint32_t method_idx,
110 jobject class_loader,
111 const DexFile& dex_file) const {
112 CompiledMethod* method = TryCompileWithSeaIR(driver,
113 code_item,
114 access_flags,
115 invoke_type,
116 class_def_idx,
117 method_idx,
118 class_loader,
119 dex_file);
120 if (method != nullptr) return method;
121
122 return ArtCompileMethod(compiler,
123 code_item,
124 access_flags,
125 invoke_type,
126 class_def_idx,
127 method_idx,
128 class_loader,
129 dex_file);
130 }
131
132 CompiledMethod* JniCompile(CompilerDriver& driver,
133 uint32_t access_flags,
134 uint32_t method_idx,
135 const DexFile& dex_file) const {
136 return ArtLLVMJniCompileMethod(driver, access_flags, method_idx, dex_file);
137 }
138
139 uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const {
140 return reinterpret_cast<uintptr_t>(method->GetEntryPointFromPortableCompiledCode());
141 }
142
143 bool WriteElf(art::File* file,
144 OatWriter* oat_writer,
145 const std::vector<const art::DexFile*>& dex_files,
146 const std::string& android_root,
147 bool is_host, const CompilerDriver& driver) const
148 OVERRIDE
149 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
150 return art::ElfWriterMclinker::Create(
151 file, oat_writer, dex_files, android_root, is_host, driver);
152 }
153
154 Backend* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const {
155 return PortableCodeGenerator(
156 cu, cu->mir_graph.get(), &cu->arena,
157 reinterpret_cast<art::llvm::LlvmCompilationUnit*>(compilation_unit));
158 }
159
160 void InitCompilationUnit(CompilationUnit& cu) const {
161 // Fused long branches not currently useful in bitcode.
162 cu.disable_opt |=
163 (1 << kBranchFusing) |
164 (1 << kSuppressExceptionEdges);
165 }
166
167 bool IsPortable() const OVERRIDE {
168 return true;
169 }
170
171 void SetBitcodeFileName(const CompilerDriver& driver, const std::string& filename) {
172 typedef void (*SetBitcodeFileNameFn)(const CompilerDriver&, const std::string&);
173
174 SetBitcodeFileNameFn set_bitcode_file_name =
175 reinterpret_cast<SetBitcodeFileNameFn>(compilerLLVMSetBitcodeFileName);
176
177 set_bitcode_file_name(driver, filename);
178 }
179
180 private:
181 DISALLOW_COPY_AND_ASSIGN(LLVMCompiler);
182};
183#endif
184
185Compiler* Compiler::Create(Compiler::Kind kind) {
186 switch (kind) {
187 case kQuick:
188 return new QuickCompiler();
189 break;
190 case kOptimizing:
191 return new OptimizingCompiler();
192 break;
193 case kPortable:
194#ifdef ART_USE_PORTABLE_COMPILER
195 return new LLVMCompiler();
196#else
197 LOG(FATAL) << "Portable compiler not compiled";
198#endif
199 break;
200 default:
201 LOG(FATAL) << "UNREACHABLE";
202 }
203 return nullptr;
204}
205
206} // namespace art