blob: 554e5e2c3ceda8ed74ae59c3e9c6f33da8279ccc [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()),
55 irb_(*compiler_llvm_->GetIRBuilder()), func_(NULL) {
56}
57
58
59MethodCompiler::~MethodCompiler() {
60}
61
62
Logan Chien0b827102011-12-20 19:46:14 +080063void MethodCompiler::CreateFunction() {
64 // LLVM function name
65 std::string func_name(LLVMLongName(method_));
66
67 // Get function type
68 llvm::FunctionType* func_type =
69 GetFunctionType(method_idx_, method_->IsStatic());
70
71 // Create function
72 func_ = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage,
73 func_name, module_);
74
75 // Set argument name
76 llvm::Function::arg_iterator arg_iter(func_->arg_begin());
77 llvm::Function::arg_iterator arg_end(func_->arg_end());
78
79 DCHECK_NE(arg_iter, arg_end);
80 arg_iter->setName("method");
81 ++arg_iter;
82
83 if (!method_->IsStatic()) {
84 DCHECK_NE(arg_iter, arg_end);
85 arg_iter->setName("this");
86 ++arg_iter;
87 }
88
89 for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
90 arg_iter->setName(StringPrintf("a%u", i));
91 }
92}
93
94
95llvm::FunctionType* MethodCompiler::GetFunctionType(uint32_t method_idx,
96 bool is_static) {
97 // Get method signature
98 DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx);
99
100 int32_t shorty_size;
101 char const* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size);
102 CHECK_GE(shorty_size, 1);
103
104 // Get return type
105 llvm::Type* ret_type = irb_.getJType(shorty[0], kAccurate);
106
107 // Get argument type
108 std::vector<llvm::Type*> args_type;
109
110 args_type.push_back(irb_.getJObjectTy()); // method object pointer
111
112 if (!is_static) {
113 args_type.push_back(irb_.getJType('L', kAccurate)); // "this" object pointer
114 }
115
116 for (int32_t i = 1; i < shorty_size; ++i) {
117 args_type.push_back(irb_.getJType(shorty[i], kAccurate));
118 }
119
120 return llvm::FunctionType::get(ret_type, args_type, false);
121}
122
123
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800124void MethodCompiler::EmitPrologue() {
Logan Chien83426162011-12-09 09:29:50 +0800125 // UNIMPLEMENTED(WARNING);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800126}
127
128
Logan Chien83426162011-12-09 09:29:50 +0800129void MethodCompiler::EmitInstructions() {
130 // UNIMPLEMENTED(WARNING);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800131}
132
133
Logan Chien83426162011-12-09 09:29:50 +0800134void MethodCompiler::EmitInstruction(uint32_t dex_pc,
135 Instruction const* insn) {
136 // UNIMPLEMENTED(WARNING);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800137}
138
139
Logan Chien83426162011-12-09 09:29:50 +0800140CompiledMethod *MethodCompiler::Compile() {
Logan Chien0b827102011-12-20 19:46:14 +0800141 // Code generation
142 CreateFunction();
143
144 EmitPrologue();
145 EmitInstructions();
146
147 // Delete the inferred register category map (won't be used anymore)
148 method_->ResetInferredRegCategoryMap();
149
150 return new CompiledMethod(insn_set_, func_);
151}
152
153
154llvm::Value* MethodCompiler::EmitLoadMethodObjectAddr() {
155 return func_->arg_begin();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800156}
Logan Chien83426162011-12-09 09:29:50 +0800157
158
159} // namespace compiler_llvm
160} // namespace art