blob: 55af6145be06d67ab14352fe78eb9016812f8d52 [file] [log] [blame]
Andreas Gampe53c913b2014-08-12 23:19:23 -07001/*
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 "llvm_compiler.h"
18
19#ifdef ART_USE_PORTABLE_COMPILER
20#include "compiler.h"
21#include "compiler_llvm.h"
22#include "dex/portable/mir_to_gbc.h"
23#include "dex_file.h"
24#include "elf_writer_mclinker.h"
25#include "mirror/art_method-inl.h"
26#endif
27
28namespace art {
29
30#ifdef ART_USE_PORTABLE_COMPILER
31
32namespace llvm {
33
34// Thread-local storage compiler worker threads
35class LLVMCompilerTls : public CompilerTls {
36 public:
37 LLVMCompilerTls() : llvm_info_(nullptr) {}
38 ~LLVMCompilerTls() {}
39
40 void* GetLLVMInfo() { return llvm_info_; }
41
42 void SetLLVMInfo(void* llvm_info) { llvm_info_ = llvm_info; }
43
44 private:
45 void* llvm_info_;
46};
47
48
49
50class LLVMCompiler FINAL : public Compiler {
51 public:
52 explicit LLVMCompiler(CompilerDriver* driver) : Compiler(driver, 1000) {}
53
54 CompilerTls* CreateNewCompilerTls() {
55 return new LLVMCompilerTls();
56 }
57
58 void Init() const OVERRIDE {
59 ArtInitCompilerContext(GetCompilerDriver());
60 }
61
62 void UnInit() const OVERRIDE {
63 ArtUnInitCompilerContext(GetCompilerDriver());
64 }
65
66 bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit* cu) const
67 OVERRIDE {
68 return true;
69 }
70
71 CompiledMethod* Compile(const DexFile::CodeItem* code_item,
72 uint32_t access_flags,
73 InvokeType invoke_type,
74 uint16_t class_def_idx,
75 uint32_t method_idx,
76 jobject class_loader,
77 const DexFile& dex_file) const OVERRIDE {
78 CompiledMethod* method = TryCompileWithSeaIR(code_item,
79 access_flags,
80 invoke_type,
81 class_def_idx,
82 method_idx,
83 class_loader,
84 dex_file);
85 if (method != nullptr) {
86 return method;
87 }
88
89 return ArtCompileMethod(GetCompilerDriver(),
90 code_item,
91 access_flags,
92 invoke_type,
93 class_def_idx,
94 method_idx,
95 class_loader,
96 dex_file);
97 }
98
99 CompiledMethod* JniCompile(uint32_t access_flags,
100 uint32_t method_idx,
101 const DexFile& dex_file) const OVERRIDE {
102 return ArtLLVMJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
103 }
104
105 uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const {
106 return reinterpret_cast<uintptr_t>(method->GetEntryPointFromPortableCompiledCode());
107 }
108
109 bool WriteElf(art::File* file,
110 OatWriter* oat_writer,
111 const std::vector<const art::DexFile*>& dex_files,
112 const std::string& android_root,
113 bool is_host, const CompilerDriver& driver) const
114 OVERRIDE
115 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
116 return art::ElfWriterMclinker::Create(
117 file, oat_writer, dex_files, android_root, is_host, driver);
118 }
119
120 Backend* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const {
121 return PortableCodeGenerator(
122 cu, cu->mir_graph.get(), &cu->arena,
123 reinterpret_cast<art::llvm::LlvmCompilationUnit*>(compilation_unit));
124 }
125
126 void InitCompilationUnit(CompilationUnit& cu) const {
127 // Fused long branches not currently useful in bitcode.
128 cu.disable_opt |=
129 (1 << kBranchFusing) |
130 (1 << kSuppressExceptionEdges);
131 }
132
133 bool IsPortable() const OVERRIDE {
134 return true;
135 }
136
137 void SetBitcodeFileName(const CompilerDriver& driver, const std::string& filename) {
138 typedef void (*SetBitcodeFileNameFn)(const CompilerDriver&, const std::string&);
139
140 SetBitcodeFileNameFn set_bitcode_file_name =
141 reinterpret_cast<SetBitcodeFileNameFn>(compilerLLVMSetBitcodeFileName);
142
143 set_bitcode_file_name(driver, filename);
144 }
145
146 private:
147 DISALLOW_COPY_AND_ASSIGN(LLVMCompiler);
148};
149
150} // namespace llvm
151#endif
152
153Compiler* CreateLLVMCompiler(CompilerDriver* driver) {
154#ifdef ART_USE_PORTABLE_COMPILER
155 return new llvm::LLVMCompiler(driver);
156#else
157 return nullptr;
158#endif
159}
160
161} // namespace art