blob: a700c69a659cc665dc4d2a26bb2243bff713ec42 [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
TDYa127706e7db2012-05-06 00:05:33 -070083 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty, JType j_ty) {
84 return CreateLoad(ptr, tbaa_.GetMemoryJType(special_ty, j_ty));
85 }
86
87 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr,
88 TBAASpecialType special_ty, JType j_ty) {
89 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
90 return CreateStore(val, ptr, tbaa_.GetMemoryJType(special_ty, j_ty));
91 }
92
TDYa1278fe384d2012-05-06 20:14:17 -070093 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
94 int64_t offset,
95 llvm::Type* type,
96 TBAASpecialType special_ty) {
TDYa127aba61122012-05-04 18:28:36 -070097 return LoadFromObjectOffset(object_addr, offset, type, tbaa_.GetSpecialType(special_ty));
98 }
99
100 void StoreToObjectOffset(llvm::Value* object_addr,
101 int64_t offset,
102 llvm::Value* new_value,
103 TBAASpecialType special_ty) {
104 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
105 StoreToObjectOffset(object_addr, offset, new_value, tbaa_.GetSpecialType(special_ty));
106 }
107
TDYa127145d4912012-05-06 21:44:45 -0700108 void SetTBAACall(llvm::CallInst* call_inst, TBAASpecialType special_ty) {
109 call_inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_.GetSpecialType(special_ty));
110 }
111
TDYa127aba61122012-05-04 18:28:36 -0700112
113 //--------------------------------------------------------------------------
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800114 // Pointer Arithmetic Helper Function
115 //--------------------------------------------------------------------------
116
117 llvm::IntegerType* getPtrEquivIntTy() {
118 return getInt32Ty();
119 }
120
121 size_t getSizeOfPtrEquivInt() {
122 return 4;
123 }
124
125 llvm::ConstantInt* getSizeOfPtrEquivIntValue() {
126 return getPtrEquivInt(getSizeOfPtrEquivInt());
127 }
128
TDYa127ee1f59b2012-04-25 00:56:40 -0700129 llvm::ConstantInt* getPtrEquivInt(int64_t i) {
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800130 return llvm::ConstantInt::get(getPtrEquivIntTy(), i);
131 }
132
133 llvm::Value* CreatePtrDisp(llvm::Value* base,
134 llvm::Value* offset,
135 llvm::PointerType* ret_ty) {
136
137 llvm::Value* base_int = CreatePtrToInt(base, getPtrEquivIntTy());
138 llvm::Value* result_int = CreateAdd(base_int, offset);
139 llvm::Value* result = CreateIntToPtr(result_int, ret_ty);
140
141 return result;
142 }
143
144 llvm::Value* CreatePtrDisp(llvm::Value* base,
145 llvm::Value* bs,
146 llvm::Value* count,
147 llvm::Value* offset,
148 llvm::PointerType* ret_ty) {
149
150 llvm::Value* block_offset = CreateMul(bs, count);
151 llvm::Value* total_offset = CreateAdd(block_offset, offset);
152
153 return CreatePtrDisp(base, total_offset, ret_ty);
154 }
155
TDYa1278fe384d2012-05-06 20:14:17 -0700156 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
157 int64_t offset,
158 llvm::Type* type,
159 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700160 // Convert offset to llvm::value
161 llvm::Value* llvm_offset = getPtrEquivInt(offset);
162 // Calculate the value's address
163 llvm::Value* value_addr = CreatePtrDisp(object_addr, llvm_offset, type->getPointerTo());
164 // Load
TDYa127aba61122012-05-04 18:28:36 -0700165 return CreateLoad(value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700166 }
167
TDYa127aba61122012-05-04 18:28:36 -0700168 void StoreToObjectOffset(llvm::Value* object_addr,
169 int64_t offset,
170 llvm::Value* new_value,
171 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700172 // Convert offset to llvm::value
173 llvm::Value* llvm_offset = getPtrEquivInt(offset);
174 // Calculate the value's address
175 llvm::Value* value_addr = CreatePtrDisp(object_addr,
176 llvm_offset,
177 new_value->getType()->getPointerTo());
178 // Store
TDYa127aba61122012-05-04 18:28:36 -0700179 CreateStore(new_value, value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700180 }
181
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800182
183 //--------------------------------------------------------------------------
Logan Chien42e0e152012-01-13 15:42:36 +0800184 // Runtime Helper Function
185 //--------------------------------------------------------------------------
186
TDYa127d668a062012-04-13 12:36:57 -0700187 llvm::Function* GetRuntime(runtime_support::RuntimeId rt) {
188 return runtime_support_->GetRuntimeSupportFunction(rt);
189 }
190
191 void SetRuntimeSupport(RuntimeSupportBuilder* runtime_support) {
192 // Can only set once. We can't do this on constructor, because RuntimeSupportBuilder needs
193 // IRBuilder.
194 if (runtime_support_ == NULL && runtime_support != NULL) {
195 runtime_support_ = runtime_support;
196 }
197 }
Logan Chien42e0e152012-01-13 15:42:36 +0800198
199
200 //--------------------------------------------------------------------------
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800201 // Type Helper Function
202 //--------------------------------------------------------------------------
203
204 llvm::Type* getJType(char shorty_jty, JTypeSpace space) {
205 return getJType(GetJTypeFromShorty(shorty_jty), space);
206 }
207
208 llvm::Type* getJType(JType jty, JTypeSpace space) {
209 switch (space) {
210 case kAccurate:
211 return getJTypeInAccurateSpace(jty);
212
213 case kReg:
214 case kField: // Currently field space is equivalent to register space.
215 return getJTypeInRegSpace(jty);
216
217 case kArray:
218 return getJTypeInArraySpace(jty);
219 }
220
Logan Chien83426162011-12-09 09:29:50 +0800221 LOG(FATAL) << "Unknown type space: " << space;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800222 return NULL;
223 }
224
225 llvm::Type* getJVoidTy() {
226 return getVoidTy();
227 }
228
229 llvm::IntegerType* getJBooleanTy() {
230 return getInt1Ty();
231 }
232
233 llvm::IntegerType* getJByteTy() {
234 return getInt8Ty();
235 }
236
237 llvm::IntegerType* getJCharTy() {
238 return getInt16Ty();
239 }
240
241 llvm::IntegerType* getJShortTy() {
242 return getInt16Ty();
243 }
244
245 llvm::IntegerType* getJIntTy() {
246 return getInt32Ty();
247 }
248
249 llvm::IntegerType* getJLongTy() {
250 return getInt64Ty();
251 }
252
253 llvm::Type* getJFloatTy() {
254 return getFloatTy();
255 }
256
257 llvm::Type* getJDoubleTy() {
258 return getDoubleTy();
259 }
260
261 llvm::PointerType* getJObjectTy() {
262 return jobject_type_;
263 }
264
Logan Chienf04364f2012-02-10 12:01:39 +0800265 llvm::PointerType* getJEnvTy() {
266 return jenv_type_;
267 }
268
269 llvm::Type* getJValueTy() {
270 // NOTE: JValue is an union type, which may contains boolean, byte, char,
271 // short, int, long, float, double, Object. However, LLVM itself does
272 // not support union type, so we have to return a type with biggest size,
273 // then bitcast it before we use it.
274 return getJLongTy();
275 }
276
Logan Chien8dfcbea2012-02-17 18:50:32 +0800277 llvm::StructType* getShadowFrameTy(uint32_t sirt_size);
278
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800279
280 //--------------------------------------------------------------------------
281 // Constant Value Helper Function
282 //--------------------------------------------------------------------------
283
284 llvm::ConstantInt* getJBoolean(bool is_true) {
285 return (is_true) ? getTrue() : getFalse();
286 }
287
288 llvm::ConstantInt* getJByte(int8_t i) {
289 return llvm::ConstantInt::getSigned(getJByteTy(), i);
290 }
291
292 llvm::ConstantInt* getJChar(int16_t i) {
293 return llvm::ConstantInt::getSigned(getJCharTy(), i);
294 }
295
296 llvm::ConstantInt* getJShort(int16_t i) {
297 return llvm::ConstantInt::getSigned(getJShortTy(), i);
298 }
299
300 llvm::ConstantInt* getJInt(int32_t i) {
301 return llvm::ConstantInt::getSigned(getJIntTy(), i);
302 }
303
304 llvm::ConstantInt* getJLong(int64_t i) {
305 return llvm::ConstantInt::getSigned(getJLongTy(), i);
306 }
307
308 llvm::Constant* getJFloat(float f) {
309 return llvm::ConstantFP::get(getJFloatTy(), f);
310 }
311
312 llvm::Constant* getJDouble(double d) {
313 return llvm::ConstantFP::get(getJDoubleTy(), d);
314 }
315
316 llvm::ConstantPointerNull* getJNull() {
317 return llvm::ConstantPointerNull::get(getJObjectTy());
318 }
319
320 llvm::Constant* getJZero(char shorty_jty) {
321 return getJZero(GetJTypeFromShorty(shorty_jty));
322 }
323
324 llvm::Constant* getJZero(JType jty) {
325 switch (jty) {
326 case kVoid:
Logan Chien83426162011-12-09 09:29:50 +0800327 LOG(FATAL) << "Zero is not a value of void type";
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800328 return NULL;
329
330 case kBoolean:
331 return getJBoolean(false);
332
333 case kByte:
334 return getJByte(0);
335
336 case kChar:
337 return getJChar(0);
338
339 case kShort:
340 return getJShort(0);
341
342 case kInt:
343 return getJInt(0);
344
345 case kLong:
346 return getJLong(0);
347
348 case kFloat:
349 return getJFloat(0.0f);
350
351 case kDouble:
352 return getJDouble(0.0);
353
354 case kObject:
355 return getJNull();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800356
TDYa127706e7db2012-05-06 00:05:33 -0700357 default:
358 LOG(FATAL) << "Unknown java type: " << jty;
359 return NULL;
360 }
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800361 }
362
363
364 private:
365 //--------------------------------------------------------------------------
366 // Type Helper Function (Private)
367 //--------------------------------------------------------------------------
368
369 llvm::Type* getJTypeInAccurateSpace(JType jty);
370 llvm::Type* getJTypeInRegSpace(JType jty);
371 llvm::Type* getJTypeInArraySpace(JType jty);
372
373
374 private:
Logan Chien6a917992012-02-17 18:43:48 +0800375 llvm::Module* module_;
376
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800377 llvm::PointerType* jobject_type_;
378
Logan Chienf04364f2012-02-10 12:01:39 +0800379 llvm::PointerType* jenv_type_;
380
Logan Chien8dfcbea2012-02-17 18:50:32 +0800381 llvm::StructType* art_frame_type_;
382
TDYa127aba61122012-05-04 18:28:36 -0700383 TBAAInfo tbaa_;
384
TDYa127d668a062012-04-13 12:36:57 -0700385 RuntimeSupportBuilder* runtime_support_;
Logan Chien42e0e152012-01-13 15:42:36 +0800386
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800387};
388
389
390} // namespace compiler_llvm
391} // namespace art
392
393#endif // ART_SRC_COMPILER_LLVM_IR_BUILDER_H_