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