blob: 0ceca0d269963085f3b13428d1b895712c39fe94 [file] [log] [blame]
Shih-wei Liaod1fec812012-02-13 09:51:10 -08001/*
2 * Copyright (C) 2012 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 "method_compiler.h"
18
Logan Chienfca7e872011-12-20 20:08:22 +080019#include "backend_types.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080020#include "compiler.h"
21#include "ir_builder.h"
22#include "logging.h"
23#include "object.h"
24#include "object_utils.h"
25#include "stl_util.h"
Logan Chien0b827102011-12-20 19:46:14 +080026#include "stringprintf.h"
27#include "utils_llvm.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080028
29#include <iomanip>
30
31#include <llvm/Analysis/Verifier.h>
32#include <llvm/Function.h>
33
Logan Chien83426162011-12-09 09:29:50 +080034namespace art {
35namespace compiler_llvm {
Shih-wei Liaod1fec812012-02-13 09:51:10 -080036
37
Logan Chien83426162011-12-09 09:29:50 +080038MethodCompiler::MethodCompiler(InstructionSet insn_set,
39 Compiler* compiler,
40 ClassLinker* class_linker,
41 ClassLoader const* class_loader,
42 DexFile const* dex_file,
43 DexCache* dex_cache,
44 DexFile::CodeItem const* code_item,
Shih-wei Liaod1fec812012-02-13 09:51:10 -080045 uint32_t method_idx,
46 uint32_t access_flags)
47: insn_set_(insn_set),
48 compiler_(compiler), compiler_llvm_(compiler->GetCompilerLLVM()),
49 class_linker_(class_linker), class_loader_(class_loader),
50 dex_file_(dex_file), dex_cache_(dex_cache), code_item_(code_item),
51 method_(dex_cache->GetResolvedMethod(method_idx)),
52 method_helper_(method_), method_idx_(method_idx),
53 access_flags_(access_flags), module_(compiler_llvm_->GetModule()),
54 context_(compiler_llvm_->GetLLVMContext()),
Logan Chiend6c239a2011-12-23 15:11:45 +080055 irb_(*compiler_llvm_->GetIRBuilder()), func_(NULL),
56 prologue_(NULL), basic_blocks_(code_item->insns_size_in_code_units_) {
Shih-wei Liaod1fec812012-02-13 09:51:10 -080057}
58
59
60MethodCompiler::~MethodCompiler() {
61}
62
63
Logan Chien0b827102011-12-20 19:46:14 +080064void MethodCompiler::CreateFunction() {
65 // LLVM function name
66 std::string func_name(LLVMLongName(method_));
67
68 // Get function type
69 llvm::FunctionType* func_type =
70 GetFunctionType(method_idx_, method_->IsStatic());
71
72 // Create function
73 func_ = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage,
74 func_name, module_);
75
76 // Set argument name
77 llvm::Function::arg_iterator arg_iter(func_->arg_begin());
78 llvm::Function::arg_iterator arg_end(func_->arg_end());
79
80 DCHECK_NE(arg_iter, arg_end);
81 arg_iter->setName("method");
82 ++arg_iter;
83
84 if (!method_->IsStatic()) {
85 DCHECK_NE(arg_iter, arg_end);
86 arg_iter->setName("this");
87 ++arg_iter;
88 }
89
90 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
91 arg_iter->setName(StringPrintf("a%u", i));
92 }
93}
94
95
96llvm::FunctionType* MethodCompiler::GetFunctionType(uint32_t method_idx,
97 bool is_static) {
98 // Get method signature
99 DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx);
100
101 int32_t shorty_size;
102 char const* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size);
103 CHECK_GE(shorty_size, 1);
104
105 // Get return type
106 llvm::Type* ret_type = irb_.getJType(shorty[0], kAccurate);
107
108 // Get argument type
109 std::vector<llvm::Type*> args_type;
110
111 args_type.push_back(irb_.getJObjectTy()); // method object pointer
112
113 if (!is_static) {
114 args_type.push_back(irb_.getJType('L', kAccurate)); // "this" object pointer
115 }
116
117 for (int32_t i = 1; i < shorty_size; ++i) {
118 args_type.push_back(irb_.getJType(shorty[i], kAccurate));
119 }
120
121 return llvm::FunctionType::get(ret_type, args_type, false);
122}
123
124
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800125void MethodCompiler::EmitPrologue() {
Logan Chien83426162011-12-09 09:29:50 +0800126 // UNIMPLEMENTED(WARNING);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800127}
128
129
Logan Chien83426162011-12-09 09:29:50 +0800130void MethodCompiler::EmitInstructions() {
Logan Chiend6c239a2011-12-23 15:11:45 +0800131 uint32_t dex_pc = 0;
132 while (dex_pc < code_item_->insns_size_in_code_units_) {
133 Instruction const* insn = Instruction::At(code_item_->insns_ + dex_pc);
134 EmitInstruction(dex_pc, insn);
135 dex_pc += insn->SizeInCodeUnits();
136 }
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800137}
138
139
Logan Chien83426162011-12-09 09:29:50 +0800140void MethodCompiler::EmitInstruction(uint32_t dex_pc,
141 Instruction const* insn) {
Logan Chiend6c239a2011-12-23 15:11:45 +0800142
143 // Set the IRBuilder insertion point
144 irb_.SetInsertPoint(GetBasicBlock(dex_pc));
145
Logan Chien83426162011-12-09 09:29:50 +0800146 // UNIMPLEMENTED(WARNING);
Logan Chiend6c239a2011-12-23 15:11:45 +0800147 irb_.CreateUnreachable();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800148}
149
150
Logan Chien83426162011-12-09 09:29:50 +0800151CompiledMethod *MethodCompiler::Compile() {
Logan Chien0b827102011-12-20 19:46:14 +0800152 // Code generation
153 CreateFunction();
154
155 EmitPrologue();
156 EmitInstructions();
157
Logan Chiend6c239a2011-12-23 15:11:45 +0800158 // Verify the generated bitcode
159 llvm::verifyFunction(*func_, llvm::PrintMessageAction);
160
Logan Chien0b827102011-12-20 19:46:14 +0800161 // Delete the inferred register category map (won't be used anymore)
162 method_->ResetInferredRegCategoryMap();
163
164 return new CompiledMethod(insn_set_, func_);
165}
166
167
168llvm::Value* MethodCompiler::EmitLoadMethodObjectAddr() {
169 return func_->arg_begin();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800170}
Logan Chien83426162011-12-09 09:29:50 +0800171
172
Logan Chiend6c239a2011-12-23 15:11:45 +0800173llvm::BasicBlock* MethodCompiler::
174CreateBasicBlockWithDexPC(uint32_t dex_pc, char const* postfix) {
175 std::string name;
176
177 if (postfix) {
178 StringAppendF(&name, "B%u.%s", dex_pc, postfix);
179 } else {
180 StringAppendF(&name, "B%u", dex_pc);
181 }
182
183 return llvm::BasicBlock::Create(*context_, name, func_);
184}
185
186
187llvm::BasicBlock* MethodCompiler::GetBasicBlock(uint32_t dex_pc) {
188 DCHECK(dex_pc < code_item_->insns_size_in_code_units_);
189
190 llvm::BasicBlock* basic_block = basic_blocks_[dex_pc];
191
192 if (!basic_block) {
193 basic_block = CreateBasicBlockWithDexPC(dex_pc);
194 basic_blocks_[dex_pc] = basic_block;
195 }
196
197 return basic_block;
198}
199
200
201llvm::BasicBlock*
202MethodCompiler::GetNextBasicBlock(uint32_t dex_pc) {
203 Instruction const* insn = Instruction::At(code_item_->insns_ + dex_pc);
204 return GetBasicBlock(dex_pc + insn->SizeInCodeUnits());
205}
206
207
Logan Chien83426162011-12-09 09:29:50 +0800208} // namespace compiler_llvm
209} // namespace art