blob: 4dbc1b5b26b4e18f2c6c5f444ac3e46ce51495b2 [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#ifndef ART_SRC_COMPILER_LLVM_IR_BUILDER_H_
18#define ART_SRC_COMPILER_LLVM_IR_BUILDER_H_
19
20#include "backend_types.h"
TDYa127d668a062012-04-13 12:36:57 -070021#include "runtime_support_builder.h"
Logan Chien42e0e152012-01-13 15:42:36 +080022#include "runtime_support_func.h"
TDYa127aba61122012-05-04 18:28:36 -070023#include "tbaa_info.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080024
25#include <llvm/Constants.h>
26#include <llvm/DerivedTypes.h>
TDYa127aba61122012-05-04 18:28:36 -070027#include <llvm/LLVMContext.h>
Shih-wei Liaod1fec812012-02-13 09:51:10 -080028#include <llvm/Support/IRBuilder.h>
29#include <llvm/Type.h>
30
31#include <stdint.h>
32
33
34namespace art {
35namespace compiler_llvm {
36
37
38typedef llvm::IRBuilder<> LLVMIRBuilder;
39// NOTE: Here we define our own LLVMIRBuilder type alias, so that we can
40// switch "preserveNames" template parameter easily.
41
42
43class IRBuilder : public LLVMIRBuilder {
44 public:
45 //--------------------------------------------------------------------------
46 // General
47 //--------------------------------------------------------------------------
48
49 IRBuilder(llvm::LLVMContext& context, llvm::Module& module);
50
51
52 //--------------------------------------------------------------------------
TDYa127aba61122012-05-04 18:28:36 -070053 // Extend load & store for TBAA
54 //--------------------------------------------------------------------------
55
56 llvm::LoadInst* CreateLoad(llvm::Value* ptr, llvm::MDNode* tbaa_info) {
57 llvm::LoadInst* inst = LLVMIRBuilder::CreateLoad(ptr);
58 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
59 return inst;
60 }
61
62 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, llvm::MDNode* tbaa_info) {
63 llvm::StoreInst* inst = LLVMIRBuilder::CreateStore(val, ptr);
64 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
65 return inst;
66 }
67
68
69 //--------------------------------------------------------------------------
70 // TBAA
71 //--------------------------------------------------------------------------
72
73 // TODO: After we design the non-special TBAA info, re-design the TBAA interface.
74 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty) {
75 return CreateLoad(ptr, tbaa_.GetSpecialType(special_ty));
76 }
77
78 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, TBAASpecialType special_ty) {
79 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
80 return CreateStore(val, ptr, tbaa_.GetSpecialType(special_ty));
81 }
82
83 llvm::Value* LoadFromObjectOffset(llvm::Value* object_addr,
84 int64_t offset,
85 llvm::Type* type,
86 TBAASpecialType special_ty) {
87 return LoadFromObjectOffset(object_addr, offset, type, tbaa_.GetSpecialType(special_ty));
88 }
89
90 void StoreToObjectOffset(llvm::Value* object_addr,
91 int64_t offset,
92 llvm::Value* new_value,
93 TBAASpecialType special_ty) {
94 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
95 StoreToObjectOffset(object_addr, offset, new_value, tbaa_.GetSpecialType(special_ty));
96 }
97
98
99 //--------------------------------------------------------------------------
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800100 // Pointer Arithmetic Helper Function
101 //--------------------------------------------------------------------------
102
103 llvm::IntegerType* getPtrEquivIntTy() {
104 return getInt32Ty();
105 }
106
107 size_t getSizeOfPtrEquivInt() {
108 return 4;
109 }
110
111 llvm::ConstantInt* getSizeOfPtrEquivIntValue() {
112 return getPtrEquivInt(getSizeOfPtrEquivInt());
113 }
114
TDYa127ee1f59b2012-04-25 00:56:40 -0700115 llvm::ConstantInt* getPtrEquivInt(int64_t i) {
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800116 return llvm::ConstantInt::get(getPtrEquivIntTy(), i);
117 }
118
119 llvm::Value* CreatePtrDisp(llvm::Value* base,
120 llvm::Value* offset,
121 llvm::PointerType* ret_ty) {
122
123 llvm::Value* base_int = CreatePtrToInt(base, getPtrEquivIntTy());
124 llvm::Value* result_int = CreateAdd(base_int, offset);
125 llvm::Value* result = CreateIntToPtr(result_int, ret_ty);
126
127 return result;
128 }
129
130 llvm::Value* CreatePtrDisp(llvm::Value* base,
131 llvm::Value* bs,
132 llvm::Value* count,
133 llvm::Value* offset,
134 llvm::PointerType* ret_ty) {
135
136 llvm::Value* block_offset = CreateMul(bs, count);
137 llvm::Value* total_offset = CreateAdd(block_offset, offset);
138
139 return CreatePtrDisp(base, total_offset, ret_ty);
140 }
141
TDYa127aba61122012-05-04 18:28:36 -0700142 llvm::Value* LoadFromObjectOffset(llvm::Value* object_addr,
143 int64_t offset,
144 llvm::Type* type,
145 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700146 // Convert offset to llvm::value
147 llvm::Value* llvm_offset = getPtrEquivInt(offset);
148 // Calculate the value's address
149 llvm::Value* value_addr = CreatePtrDisp(object_addr, llvm_offset, type->getPointerTo());
150 // Load
TDYa127aba61122012-05-04 18:28:36 -0700151 return CreateLoad(value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700152 }
153
TDYa127aba61122012-05-04 18:28:36 -0700154 void StoreToObjectOffset(llvm::Value* object_addr,
155 int64_t offset,
156 llvm::Value* new_value,
157 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700158 // Convert offset to llvm::value
159 llvm::Value* llvm_offset = getPtrEquivInt(offset);
160 // Calculate the value's address
161 llvm::Value* value_addr = CreatePtrDisp(object_addr,
162 llvm_offset,
163 new_value->getType()->getPointerTo());
164 // Store
TDYa127aba61122012-05-04 18:28:36 -0700165 CreateStore(new_value, value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700166 }
167
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800168
169 //--------------------------------------------------------------------------
Logan Chien42e0e152012-01-13 15:42:36 +0800170 // Runtime Helper Function
171 //--------------------------------------------------------------------------
172
TDYa127d668a062012-04-13 12:36:57 -0700173 llvm::Function* GetRuntime(runtime_support::RuntimeId rt) {
174 return runtime_support_->GetRuntimeSupportFunction(rt);
175 }
176
177 void SetRuntimeSupport(RuntimeSupportBuilder* runtime_support) {
178 // Can only set once. We can't do this on constructor, because RuntimeSupportBuilder needs
179 // IRBuilder.
180 if (runtime_support_ == NULL && runtime_support != NULL) {
181 runtime_support_ = runtime_support;
182 }
183 }
Logan Chien42e0e152012-01-13 15:42:36 +0800184
185
186 //--------------------------------------------------------------------------
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800187 // Type Helper Function
188 //--------------------------------------------------------------------------
189
190 llvm::Type* getJType(char shorty_jty, JTypeSpace space) {
191 return getJType(GetJTypeFromShorty(shorty_jty), space);
192 }
193
194 llvm::Type* getJType(JType jty, JTypeSpace space) {
195 switch (space) {
196 case kAccurate:
197 return getJTypeInAccurateSpace(jty);
198
199 case kReg:
200 case kField: // Currently field space is equivalent to register space.
201 return getJTypeInRegSpace(jty);
202
203 case kArray:
204 return getJTypeInArraySpace(jty);
205 }
206
Logan Chien83426162011-12-09 09:29:50 +0800207 LOG(FATAL) << "Unknown type space: " << space;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800208 return NULL;
209 }
210
211 llvm::Type* getJVoidTy() {
212 return getVoidTy();
213 }
214
215 llvm::IntegerType* getJBooleanTy() {
216 return getInt1Ty();
217 }
218
219 llvm::IntegerType* getJByteTy() {
220 return getInt8Ty();
221 }
222
223 llvm::IntegerType* getJCharTy() {
224 return getInt16Ty();
225 }
226
227 llvm::IntegerType* getJShortTy() {
228 return getInt16Ty();
229 }
230
231 llvm::IntegerType* getJIntTy() {
232 return getInt32Ty();
233 }
234
235 llvm::IntegerType* getJLongTy() {
236 return getInt64Ty();
237 }
238
239 llvm::Type* getJFloatTy() {
240 return getFloatTy();
241 }
242
243 llvm::Type* getJDoubleTy() {
244 return getDoubleTy();
245 }
246
247 llvm::PointerType* getJObjectTy() {
248 return jobject_type_;
249 }
250
Logan Chienf04364f2012-02-10 12:01:39 +0800251 llvm::PointerType* getJEnvTy() {
252 return jenv_type_;
253 }
254
255 llvm::Type* getJValueTy() {
256 // NOTE: JValue is an union type, which may contains boolean, byte, char,
257 // short, int, long, float, double, Object. However, LLVM itself does
258 // not support union type, so we have to return a type with biggest size,
259 // then bitcast it before we use it.
260 return getJLongTy();
261 }
262
Logan Chien8dfcbea2012-02-17 18:50:32 +0800263 llvm::StructType* getShadowFrameTy(uint32_t sirt_size);
264
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800265
266 //--------------------------------------------------------------------------
267 // Constant Value Helper Function
268 //--------------------------------------------------------------------------
269
270 llvm::ConstantInt* getJBoolean(bool is_true) {
271 return (is_true) ? getTrue() : getFalse();
272 }
273
274 llvm::ConstantInt* getJByte(int8_t i) {
275 return llvm::ConstantInt::getSigned(getJByteTy(), i);
276 }
277
278 llvm::ConstantInt* getJChar(int16_t i) {
279 return llvm::ConstantInt::getSigned(getJCharTy(), i);
280 }
281
282 llvm::ConstantInt* getJShort(int16_t i) {
283 return llvm::ConstantInt::getSigned(getJShortTy(), i);
284 }
285
286 llvm::ConstantInt* getJInt(int32_t i) {
287 return llvm::ConstantInt::getSigned(getJIntTy(), i);
288 }
289
290 llvm::ConstantInt* getJLong(int64_t i) {
291 return llvm::ConstantInt::getSigned(getJLongTy(), i);
292 }
293
294 llvm::Constant* getJFloat(float f) {
295 return llvm::ConstantFP::get(getJFloatTy(), f);
296 }
297
298 llvm::Constant* getJDouble(double d) {
299 return llvm::ConstantFP::get(getJDoubleTy(), d);
300 }
301
302 llvm::ConstantPointerNull* getJNull() {
303 return llvm::ConstantPointerNull::get(getJObjectTy());
304 }
305
306 llvm::Constant* getJZero(char shorty_jty) {
307 return getJZero(GetJTypeFromShorty(shorty_jty));
308 }
309
310 llvm::Constant* getJZero(JType jty) {
311 switch (jty) {
312 case kVoid:
Logan Chien83426162011-12-09 09:29:50 +0800313 LOG(FATAL) << "Zero is not a value of void type";
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800314 return NULL;
315
316 case kBoolean:
317 return getJBoolean(false);
318
319 case kByte:
320 return getJByte(0);
321
322 case kChar:
323 return getJChar(0);
324
325 case kShort:
326 return getJShort(0);
327
328 case kInt:
329 return getJInt(0);
330
331 case kLong:
332 return getJLong(0);
333
334 case kFloat:
335 return getJFloat(0.0f);
336
337 case kDouble:
338 return getJDouble(0.0);
339
340 case kObject:
341 return getJNull();
342 }
343
344 LOG(FATAL) << "Unknown java type: " << jty;
345 return NULL;
346 }
347
348
349 private:
350 //--------------------------------------------------------------------------
351 // Type Helper Function (Private)
352 //--------------------------------------------------------------------------
353
354 llvm::Type* getJTypeInAccurateSpace(JType jty);
355 llvm::Type* getJTypeInRegSpace(JType jty);
356 llvm::Type* getJTypeInArraySpace(JType jty);
357
358
359 private:
Logan Chien6a917992012-02-17 18:43:48 +0800360 llvm::Module* module_;
361
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800362 llvm::PointerType* jobject_type_;
363
Logan Chienf04364f2012-02-10 12:01:39 +0800364 llvm::PointerType* jenv_type_;
365
Logan Chien8dfcbea2012-02-17 18:50:32 +0800366 llvm::StructType* art_frame_type_;
367
TDYa127aba61122012-05-04 18:28:36 -0700368 TBAAInfo tbaa_;
369
TDYa127d668a062012-04-13 12:36:57 -0700370 RuntimeSupportBuilder* runtime_support_;
Logan Chien42e0e152012-01-13 15:42:36 +0800371
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800372};
373
374
375} // namespace compiler_llvm
376} // namespace art
377
378#endif // ART_SRC_COMPILER_LLVM_IR_BUILDER_H_