blob: 5df9831abc19837b8e00b597804f89c69fbdb303 [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"
TDYa1271f196f12012-07-11 20:50:22 -070021#include "md_builder.h"
TDYa127d668a062012-04-13 12:36:57 -070022#include "runtime_support_builder.h"
Logan Chien42e0e152012-01-13 15:42:36 +080023#include "runtime_support_func.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) {
TDYa1271f196f12012-07-11 20:50:22 -070075 return CreateLoad(ptr, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -070076 }
77
78 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, TBAASpecialType special_ty) {
79 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -070080 return CreateStore(val, ptr, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -070081 }
82
TDYa127706e7db2012-05-06 00:05:33 -070083 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty, JType j_ty) {
TDYa1271f196f12012-07-11 20:50:22 -070084 return CreateLoad(ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa127706e7db2012-05-06 00:05:33 -070085 }
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!";
TDYa1271f196f12012-07-11 20:50:22 -070090 return CreateStore(val, ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa127706e7db2012-05-06 00:05:33 -070091 }
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) {
TDYa1271f196f12012-07-11 20:50:22 -070097 return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -070098 }
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!";
TDYa1271f196f12012-07-11 20:50:22 -0700105 StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700106 }
107
TDYa12729c0cd12012-05-17 04:51:08 -0700108 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
109 int64_t offset,
110 llvm::Type* type,
111 TBAASpecialType special_ty, JType j_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700112 return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa12729c0cd12012-05-17 04:51:08 -0700113 }
114
115 void StoreToObjectOffset(llvm::Value* object_addr,
116 int64_t offset,
117 llvm::Value* new_value,
118 TBAASpecialType special_ty, JType j_ty) {
119 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700120 StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa12729c0cd12012-05-17 04:51:08 -0700121 }
122
TDYa127de479be2012-05-31 08:03:26 -0700123 void SetTBAA(llvm::Instruction* inst, TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700124 inst->setMetadata(llvm::LLVMContext::MD_tbaa, mdb_.GetTBAASpecialType(special_ty));
TDYa127145d4912012-05-06 21:44:45 -0700125 }
126
TDYa127aba61122012-05-04 18:28:36 -0700127
128 //--------------------------------------------------------------------------
TDYa127ac7b5bb2012-05-11 13:17:49 -0700129 // Static Branch Prediction
130 //--------------------------------------------------------------------------
131
132 // Import the orignal conditional branch
133 using LLVMIRBuilder::CreateCondBr;
134 llvm::BranchInst* CreateCondBr(llvm::Value *cond,
135 llvm::BasicBlock* true_bb,
136 llvm::BasicBlock* false_bb,
137 ExpectCond expect) {
TDYa1271f196f12012-07-11 20:50:22 -0700138 llvm::BranchInst* branch_inst = CreateCondBr(cond, true_bb, false_bb);
139 branch_inst->setMetadata(llvm::LLVMContext::MD_prof, mdb_.GetBranchWeights(expect));
TDYa127ac7b5bb2012-05-11 13:17:49 -0700140 return branch_inst;
141 }
142
143
144 //--------------------------------------------------------------------------
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800145 // Pointer Arithmetic Helper Function
146 //--------------------------------------------------------------------------
147
148 llvm::IntegerType* getPtrEquivIntTy() {
149 return getInt32Ty();
150 }
151
152 size_t getSizeOfPtrEquivInt() {
153 return 4;
154 }
155
156 llvm::ConstantInt* getSizeOfPtrEquivIntValue() {
157 return getPtrEquivInt(getSizeOfPtrEquivInt());
158 }
159
TDYa127ee1f59b2012-04-25 00:56:40 -0700160 llvm::ConstantInt* getPtrEquivInt(int64_t i) {
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800161 return llvm::ConstantInt::get(getPtrEquivIntTy(), i);
162 }
163
164 llvm::Value* CreatePtrDisp(llvm::Value* base,
165 llvm::Value* offset,
166 llvm::PointerType* ret_ty) {
167
168 llvm::Value* base_int = CreatePtrToInt(base, getPtrEquivIntTy());
169 llvm::Value* result_int = CreateAdd(base_int, offset);
170 llvm::Value* result = CreateIntToPtr(result_int, ret_ty);
171
172 return result;
173 }
174
175 llvm::Value* CreatePtrDisp(llvm::Value* base,
176 llvm::Value* bs,
177 llvm::Value* count,
178 llvm::Value* offset,
179 llvm::PointerType* ret_ty) {
180
181 llvm::Value* block_offset = CreateMul(bs, count);
182 llvm::Value* total_offset = CreateAdd(block_offset, offset);
183
184 return CreatePtrDisp(base, total_offset, ret_ty);
185 }
186
TDYa1278fe384d2012-05-06 20:14:17 -0700187 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
188 int64_t offset,
189 llvm::Type* type,
190 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700191 // Convert offset to llvm::value
192 llvm::Value* llvm_offset = getPtrEquivInt(offset);
193 // Calculate the value's address
194 llvm::Value* value_addr = CreatePtrDisp(object_addr, llvm_offset, type->getPointerTo());
195 // Load
TDYa127aba61122012-05-04 18:28:36 -0700196 return CreateLoad(value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700197 }
198
TDYa127aba61122012-05-04 18:28:36 -0700199 void StoreToObjectOffset(llvm::Value* object_addr,
200 int64_t offset,
201 llvm::Value* new_value,
202 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700203 // Convert offset to llvm::value
204 llvm::Value* llvm_offset = getPtrEquivInt(offset);
205 // Calculate the value's address
206 llvm::Value* value_addr = CreatePtrDisp(object_addr,
207 llvm_offset,
208 new_value->getType()->getPointerTo());
209 // Store
TDYa127aba61122012-05-04 18:28:36 -0700210 CreateStore(new_value, value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700211 }
212
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800213
214 //--------------------------------------------------------------------------
Logan Chien42e0e152012-01-13 15:42:36 +0800215 // Runtime Helper Function
216 //--------------------------------------------------------------------------
217
TDYa127de479be2012-05-31 08:03:26 -0700218 RuntimeSupportBuilder& Runtime() {
219 return *runtime_support_;
220 }
221
222 // TODO: Deprecate
TDYa127d668a062012-04-13 12:36:57 -0700223 llvm::Function* GetRuntime(runtime_support::RuntimeId rt) {
224 return runtime_support_->GetRuntimeSupportFunction(rt);
225 }
226
TDYa127de479be2012-05-31 08:03:26 -0700227 // TODO: Deprecate
TDYa127d668a062012-04-13 12:36:57 -0700228 void SetRuntimeSupport(RuntimeSupportBuilder* runtime_support) {
229 // Can only set once. We can't do this on constructor, because RuntimeSupportBuilder needs
230 // IRBuilder.
231 if (runtime_support_ == NULL && runtime_support != NULL) {
232 runtime_support_ = runtime_support;
233 }
234 }
Logan Chien42e0e152012-01-13 15:42:36 +0800235
236
237 //--------------------------------------------------------------------------
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800238 // Type Helper Function
239 //--------------------------------------------------------------------------
240
241 llvm::Type* getJType(char shorty_jty, JTypeSpace space) {
242 return getJType(GetJTypeFromShorty(shorty_jty), space);
243 }
244
245 llvm::Type* getJType(JType jty, JTypeSpace space) {
246 switch (space) {
247 case kAccurate:
248 return getJTypeInAccurateSpace(jty);
249
250 case kReg:
251 case kField: // Currently field space is equivalent to register space.
252 return getJTypeInRegSpace(jty);
253
254 case kArray:
255 return getJTypeInArraySpace(jty);
256 }
257
Logan Chien83426162011-12-09 09:29:50 +0800258 LOG(FATAL) << "Unknown type space: " << space;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800259 return NULL;
260 }
261
262 llvm::Type* getJVoidTy() {
263 return getVoidTy();
264 }
265
266 llvm::IntegerType* getJBooleanTy() {
267 return getInt1Ty();
268 }
269
270 llvm::IntegerType* getJByteTy() {
271 return getInt8Ty();
272 }
273
274 llvm::IntegerType* getJCharTy() {
275 return getInt16Ty();
276 }
277
278 llvm::IntegerType* getJShortTy() {
279 return getInt16Ty();
280 }
281
282 llvm::IntegerType* getJIntTy() {
283 return getInt32Ty();
284 }
285
286 llvm::IntegerType* getJLongTy() {
287 return getInt64Ty();
288 }
289
290 llvm::Type* getJFloatTy() {
291 return getFloatTy();
292 }
293
294 llvm::Type* getJDoubleTy() {
295 return getDoubleTy();
296 }
297
298 llvm::PointerType* getJObjectTy() {
299 return jobject_type_;
300 }
301
TDYa1270de52be2012-05-27 20:49:31 -0700302 llvm::Type* getArtFrameTy() {
303 return art_frame_type_;
304 }
305
Logan Chienf04364f2012-02-10 12:01:39 +0800306 llvm::PointerType* getJEnvTy() {
307 return jenv_type_;
308 }
309
310 llvm::Type* getJValueTy() {
311 // NOTE: JValue is an union type, which may contains boolean, byte, char,
312 // short, int, long, float, double, Object. However, LLVM itself does
313 // not support union type, so we have to return a type with biggest size,
314 // then bitcast it before we use it.
315 return getJLongTy();
316 }
317
Logan Chien8dfcbea2012-02-17 18:50:32 +0800318 llvm::StructType* getShadowFrameTy(uint32_t sirt_size);
319
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800320
321 //--------------------------------------------------------------------------
322 // Constant Value Helper Function
323 //--------------------------------------------------------------------------
324
325 llvm::ConstantInt* getJBoolean(bool is_true) {
326 return (is_true) ? getTrue() : getFalse();
327 }
328
329 llvm::ConstantInt* getJByte(int8_t i) {
330 return llvm::ConstantInt::getSigned(getJByteTy(), i);
331 }
332
333 llvm::ConstantInt* getJChar(int16_t i) {
334 return llvm::ConstantInt::getSigned(getJCharTy(), i);
335 }
336
337 llvm::ConstantInt* getJShort(int16_t i) {
338 return llvm::ConstantInt::getSigned(getJShortTy(), i);
339 }
340
341 llvm::ConstantInt* getJInt(int32_t i) {
342 return llvm::ConstantInt::getSigned(getJIntTy(), i);
343 }
344
345 llvm::ConstantInt* getJLong(int64_t i) {
346 return llvm::ConstantInt::getSigned(getJLongTy(), i);
347 }
348
349 llvm::Constant* getJFloat(float f) {
350 return llvm::ConstantFP::get(getJFloatTy(), f);
351 }
352
353 llvm::Constant* getJDouble(double d) {
354 return llvm::ConstantFP::get(getJDoubleTy(), d);
355 }
356
357 llvm::ConstantPointerNull* getJNull() {
358 return llvm::ConstantPointerNull::get(getJObjectTy());
359 }
360
361 llvm::Constant* getJZero(char shorty_jty) {
362 return getJZero(GetJTypeFromShorty(shorty_jty));
363 }
364
365 llvm::Constant* getJZero(JType jty) {
366 switch (jty) {
367 case kVoid:
Logan Chien83426162011-12-09 09:29:50 +0800368 LOG(FATAL) << "Zero is not a value of void type";
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800369 return NULL;
370
371 case kBoolean:
372 return getJBoolean(false);
373
374 case kByte:
375 return getJByte(0);
376
377 case kChar:
378 return getJChar(0);
379
380 case kShort:
381 return getJShort(0);
382
383 case kInt:
384 return getJInt(0);
385
386 case kLong:
387 return getJLong(0);
388
389 case kFloat:
390 return getJFloat(0.0f);
391
392 case kDouble:
393 return getJDouble(0.0);
394
395 case kObject:
396 return getJNull();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800397
TDYa127706e7db2012-05-06 00:05:33 -0700398 default:
399 LOG(FATAL) << "Unknown java type: " << jty;
400 return NULL;
401 }
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800402 }
403
404
405 private:
406 //--------------------------------------------------------------------------
407 // Type Helper Function (Private)
408 //--------------------------------------------------------------------------
409
410 llvm::Type* getJTypeInAccurateSpace(JType jty);
411 llvm::Type* getJTypeInRegSpace(JType jty);
412 llvm::Type* getJTypeInArraySpace(JType jty);
413
414
415 private:
Logan Chien6a917992012-02-17 18:43:48 +0800416 llvm::Module* module_;
417
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800418 llvm::PointerType* jobject_type_;
419
Logan Chienf04364f2012-02-10 12:01:39 +0800420 llvm::PointerType* jenv_type_;
421
Logan Chien8dfcbea2012-02-17 18:50:32 +0800422 llvm::StructType* art_frame_type_;
423
TDYa1271f196f12012-07-11 20:50:22 -0700424 MDBuilder mdb_;
TDYa127aba61122012-05-04 18:28:36 -0700425
TDYa127d668a062012-04-13 12:36:57 -0700426 RuntimeSupportBuilder* runtime_support_;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800427};
428
429
430} // namespace compiler_llvm
431} // namespace art
432
433#endif // ART_SRC_COMPILER_LLVM_IR_BUILDER_H_