blob: 60a0f2ad39fbf9711163cc16f7ef9fd43c80e32c [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
Sebastien Hertz50a1abf2013-02-18 14:36:41 +010068 llvm::AtomicCmpXchgInst*
69 CreateAtomicCmpXchgInst(llvm::Value* ptr, llvm::Value* cmp, llvm::Value* val,
70 llvm::MDNode* tbaa_info) {
71 llvm::AtomicCmpXchgInst* inst =
72 LLVMIRBuilder::CreateAtomicCmpXchg(ptr, cmp, val, llvm::Acquire);
73 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
74 return inst;
75 }
76
TDYa127aba61122012-05-04 18:28:36 -070077
78 //--------------------------------------------------------------------------
79 // TBAA
80 //--------------------------------------------------------------------------
81
82 // TODO: After we design the non-special TBAA info, re-design the TBAA interface.
83 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -070084 return CreateLoad(ptr, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -070085 }
86
87 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, TBAASpecialType special_ty) {
88 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -070089 return CreateStore(val, ptr, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -070090 }
91
TDYa127706e7db2012-05-06 00:05:33 -070092 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty, JType j_ty) {
TDYa1271f196f12012-07-11 20:50:22 -070093 return CreateLoad(ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa127706e7db2012-05-06 00:05:33 -070094 }
95
96 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr,
97 TBAASpecialType special_ty, JType j_ty) {
98 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -070099 return CreateStore(val, ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa127706e7db2012-05-06 00:05:33 -0700100 }
101
TDYa1278fe384d2012-05-06 20:14:17 -0700102 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
103 int64_t offset,
104 llvm::Type* type,
105 TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700106 return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700107 }
108
109 void StoreToObjectOffset(llvm::Value* object_addr,
110 int64_t offset,
111 llvm::Value* new_value,
112 TBAASpecialType special_ty) {
113 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700114 StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700115 }
116
TDYa12729c0cd12012-05-17 04:51:08 -0700117 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
118 int64_t offset,
119 llvm::Type* type,
120 TBAASpecialType special_ty, JType j_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700121 return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa12729c0cd12012-05-17 04:51:08 -0700122 }
123
124 void StoreToObjectOffset(llvm::Value* object_addr,
125 int64_t offset,
126 llvm::Value* new_value,
127 TBAASpecialType special_ty, JType j_ty) {
128 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700129 StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa12729c0cd12012-05-17 04:51:08 -0700130 }
131
Sebastien Hertz50a1abf2013-02-18 14:36:41 +0100132 llvm::AtomicCmpXchgInst*
133 CompareExchangeObjectOffset(llvm::Value* object_addr,
134 int64_t offset,
135 llvm::Value* cmp_value,
136 llvm::Value* new_value,
137 TBAASpecialType special_ty) {
138 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
139 return CompareExchangeObjectOffset(object_addr, offset, cmp_value, new_value,
140 mdb_.GetTBAASpecialType(special_ty));
141 }
142
TDYa127de479be2012-05-31 08:03:26 -0700143 void SetTBAA(llvm::Instruction* inst, TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700144 inst->setMetadata(llvm::LLVMContext::MD_tbaa, mdb_.GetTBAASpecialType(special_ty));
TDYa127145d4912012-05-06 21:44:45 -0700145 }
146
TDYa127aba61122012-05-04 18:28:36 -0700147
148 //--------------------------------------------------------------------------
TDYa127ac7b5bb2012-05-11 13:17:49 -0700149 // Static Branch Prediction
150 //--------------------------------------------------------------------------
151
152 // Import the orignal conditional branch
153 using LLVMIRBuilder::CreateCondBr;
154 llvm::BranchInst* CreateCondBr(llvm::Value *cond,
155 llvm::BasicBlock* true_bb,
156 llvm::BasicBlock* false_bb,
157 ExpectCond expect) {
TDYa1271f196f12012-07-11 20:50:22 -0700158 llvm::BranchInst* branch_inst = CreateCondBr(cond, true_bb, false_bb);
159 branch_inst->setMetadata(llvm::LLVMContext::MD_prof, mdb_.GetBranchWeights(expect));
TDYa127ac7b5bb2012-05-11 13:17:49 -0700160 return branch_inst;
161 }
162
163
164 //--------------------------------------------------------------------------
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800165 // Pointer Arithmetic Helper Function
166 //--------------------------------------------------------------------------
167
168 llvm::IntegerType* getPtrEquivIntTy() {
169 return getInt32Ty();
170 }
171
172 size_t getSizeOfPtrEquivInt() {
173 return 4;
174 }
175
176 llvm::ConstantInt* getSizeOfPtrEquivIntValue() {
177 return getPtrEquivInt(getSizeOfPtrEquivInt());
178 }
179
TDYa127ee1f59b2012-04-25 00:56:40 -0700180 llvm::ConstantInt* getPtrEquivInt(int64_t i) {
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800181 return llvm::ConstantInt::get(getPtrEquivIntTy(), i);
182 }
183
184 llvm::Value* CreatePtrDisp(llvm::Value* base,
185 llvm::Value* offset,
186 llvm::PointerType* ret_ty) {
187
188 llvm::Value* base_int = CreatePtrToInt(base, getPtrEquivIntTy());
189 llvm::Value* result_int = CreateAdd(base_int, offset);
190 llvm::Value* result = CreateIntToPtr(result_int, ret_ty);
191
192 return result;
193 }
194
195 llvm::Value* CreatePtrDisp(llvm::Value* base,
196 llvm::Value* bs,
197 llvm::Value* count,
198 llvm::Value* offset,
199 llvm::PointerType* ret_ty) {
200
201 llvm::Value* block_offset = CreateMul(bs, count);
202 llvm::Value* total_offset = CreateAdd(block_offset, offset);
203
204 return CreatePtrDisp(base, total_offset, ret_ty);
205 }
206
TDYa1278fe384d2012-05-06 20:14:17 -0700207 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
208 int64_t offset,
209 llvm::Type* type,
210 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700211 // Convert offset to llvm::value
212 llvm::Value* llvm_offset = getPtrEquivInt(offset);
213 // Calculate the value's address
214 llvm::Value* value_addr = CreatePtrDisp(object_addr, llvm_offset, type->getPointerTo());
215 // Load
TDYa127aba61122012-05-04 18:28:36 -0700216 return CreateLoad(value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700217 }
218
TDYa127aba61122012-05-04 18:28:36 -0700219 void StoreToObjectOffset(llvm::Value* object_addr,
220 int64_t offset,
221 llvm::Value* new_value,
222 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700223 // Convert offset to llvm::value
224 llvm::Value* llvm_offset = getPtrEquivInt(offset);
225 // Calculate the value's address
226 llvm::Value* value_addr = CreatePtrDisp(object_addr,
227 llvm_offset,
228 new_value->getType()->getPointerTo());
229 // Store
TDYa127aba61122012-05-04 18:28:36 -0700230 CreateStore(new_value, value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700231 }
232
Sebastien Hertz50a1abf2013-02-18 14:36:41 +0100233 llvm::AtomicCmpXchgInst* CompareExchangeObjectOffset(llvm::Value* object_addr,
234 int64_t offset,
235 llvm::Value* cmp_value,
236 llvm::Value* new_value,
237 llvm::MDNode* tbaa_info) {
238 // Convert offset to llvm::value
239 llvm::Value* llvm_offset = getPtrEquivInt(offset);
240 // Calculate the value's address
241 llvm::Value* value_addr = CreatePtrDisp(object_addr,
242 llvm_offset,
243 new_value->getType()->getPointerTo());
244 // Atomic compare and exchange
245 return CreateAtomicCmpXchgInst(value_addr, cmp_value, new_value, tbaa_info);
246 }
247
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800248
249 //--------------------------------------------------------------------------
Logan Chien42e0e152012-01-13 15:42:36 +0800250 // Runtime Helper Function
251 //--------------------------------------------------------------------------
252
TDYa127de479be2012-05-31 08:03:26 -0700253 RuntimeSupportBuilder& Runtime() {
254 return *runtime_support_;
255 }
256
257 // TODO: Deprecate
TDYa127d668a062012-04-13 12:36:57 -0700258 llvm::Function* GetRuntime(runtime_support::RuntimeId rt) {
259 return runtime_support_->GetRuntimeSupportFunction(rt);
260 }
261
TDYa127de479be2012-05-31 08:03:26 -0700262 // TODO: Deprecate
TDYa127d668a062012-04-13 12:36:57 -0700263 void SetRuntimeSupport(RuntimeSupportBuilder* runtime_support) {
264 // Can only set once. We can't do this on constructor, because RuntimeSupportBuilder needs
265 // IRBuilder.
266 if (runtime_support_ == NULL && runtime_support != NULL) {
267 runtime_support_ = runtime_support;
268 }
269 }
Logan Chien42e0e152012-01-13 15:42:36 +0800270
271
272 //--------------------------------------------------------------------------
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800273 // Type Helper Function
274 //--------------------------------------------------------------------------
275
276 llvm::Type* getJType(char shorty_jty, JTypeSpace space) {
277 return getJType(GetJTypeFromShorty(shorty_jty), space);
278 }
279
280 llvm::Type* getJType(JType jty, JTypeSpace space) {
281 switch (space) {
282 case kAccurate:
283 return getJTypeInAccurateSpace(jty);
284
285 case kReg:
286 case kField: // Currently field space is equivalent to register space.
287 return getJTypeInRegSpace(jty);
288
289 case kArray:
290 return getJTypeInArraySpace(jty);
291 }
292
Logan Chien83426162011-12-09 09:29:50 +0800293 LOG(FATAL) << "Unknown type space: " << space;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800294 return NULL;
295 }
296
297 llvm::Type* getJVoidTy() {
298 return getVoidTy();
299 }
300
301 llvm::IntegerType* getJBooleanTy() {
302 return getInt1Ty();
303 }
304
305 llvm::IntegerType* getJByteTy() {
306 return getInt8Ty();
307 }
308
309 llvm::IntegerType* getJCharTy() {
310 return getInt16Ty();
311 }
312
313 llvm::IntegerType* getJShortTy() {
314 return getInt16Ty();
315 }
316
317 llvm::IntegerType* getJIntTy() {
318 return getInt32Ty();
319 }
320
321 llvm::IntegerType* getJLongTy() {
322 return getInt64Ty();
323 }
324
325 llvm::Type* getJFloatTy() {
326 return getFloatTy();
327 }
328
329 llvm::Type* getJDoubleTy() {
330 return getDoubleTy();
331 }
332
333 llvm::PointerType* getJObjectTy() {
334 return jobject_type_;
335 }
336
TDYa1270de52be2012-05-27 20:49:31 -0700337 llvm::Type* getArtFrameTy() {
338 return art_frame_type_;
339 }
340
Logan Chienf04364f2012-02-10 12:01:39 +0800341 llvm::PointerType* getJEnvTy() {
342 return jenv_type_;
343 }
344
345 llvm::Type* getJValueTy() {
346 // NOTE: JValue is an union type, which may contains boolean, byte, char,
347 // short, int, long, float, double, Object. However, LLVM itself does
348 // not support union type, so we have to return a type with biggest size,
349 // then bitcast it before we use it.
350 return getJLongTy();
351 }
352
TDYa127ce4cc0d2012-11-18 16:59:53 -0800353 llvm::StructType* getShadowFrameTy(uint32_t vreg_size);
Logan Chien8dfcbea2012-02-17 18:50:32 +0800354
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800355
356 //--------------------------------------------------------------------------
357 // Constant Value Helper Function
358 //--------------------------------------------------------------------------
359
360 llvm::ConstantInt* getJBoolean(bool is_true) {
361 return (is_true) ? getTrue() : getFalse();
362 }
363
364 llvm::ConstantInt* getJByte(int8_t i) {
365 return llvm::ConstantInt::getSigned(getJByteTy(), i);
366 }
367
368 llvm::ConstantInt* getJChar(int16_t i) {
369 return llvm::ConstantInt::getSigned(getJCharTy(), i);
370 }
371
372 llvm::ConstantInt* getJShort(int16_t i) {
373 return llvm::ConstantInt::getSigned(getJShortTy(), i);
374 }
375
376 llvm::ConstantInt* getJInt(int32_t i) {
377 return llvm::ConstantInt::getSigned(getJIntTy(), i);
378 }
379
380 llvm::ConstantInt* getJLong(int64_t i) {
381 return llvm::ConstantInt::getSigned(getJLongTy(), i);
382 }
383
384 llvm::Constant* getJFloat(float f) {
385 return llvm::ConstantFP::get(getJFloatTy(), f);
386 }
387
388 llvm::Constant* getJDouble(double d) {
389 return llvm::ConstantFP::get(getJDoubleTy(), d);
390 }
391
392 llvm::ConstantPointerNull* getJNull() {
393 return llvm::ConstantPointerNull::get(getJObjectTy());
394 }
395
396 llvm::Constant* getJZero(char shorty_jty) {
397 return getJZero(GetJTypeFromShorty(shorty_jty));
398 }
399
400 llvm::Constant* getJZero(JType jty) {
401 switch (jty) {
402 case kVoid:
Logan Chien83426162011-12-09 09:29:50 +0800403 LOG(FATAL) << "Zero is not a value of void type";
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800404 return NULL;
405
406 case kBoolean:
407 return getJBoolean(false);
408
409 case kByte:
410 return getJByte(0);
411
412 case kChar:
413 return getJChar(0);
414
415 case kShort:
416 return getJShort(0);
417
418 case kInt:
419 return getJInt(0);
420
421 case kLong:
422 return getJLong(0);
423
424 case kFloat:
425 return getJFloat(0.0f);
426
427 case kDouble:
428 return getJDouble(0.0);
429
430 case kObject:
431 return getJNull();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800432
TDYa127706e7db2012-05-06 00:05:33 -0700433 default:
434 LOG(FATAL) << "Unknown java type: " << jty;
435 return NULL;
436 }
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800437 }
438
439
440 private:
441 //--------------------------------------------------------------------------
442 // Type Helper Function (Private)
443 //--------------------------------------------------------------------------
444
445 llvm::Type* getJTypeInAccurateSpace(JType jty);
446 llvm::Type* getJTypeInRegSpace(JType jty);
447 llvm::Type* getJTypeInArraySpace(JType jty);
448
449
450 private:
Logan Chien6a917992012-02-17 18:43:48 +0800451 llvm::Module* module_;
452
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800453 llvm::PointerType* jobject_type_;
454
Logan Chienf04364f2012-02-10 12:01:39 +0800455 llvm::PointerType* jenv_type_;
456
Logan Chien8dfcbea2012-02-17 18:50:32 +0800457 llvm::StructType* art_frame_type_;
458
TDYa1271f196f12012-07-11 20:50:22 -0700459 MDBuilder mdb_;
TDYa127aba61122012-05-04 18:28:36 -0700460
TDYa127d668a062012-04-13 12:36:57 -0700461 RuntimeSupportBuilder* runtime_support_;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800462};
463
464
465} // namespace compiler_llvm
466} // namespace art
467
468#endif // ART_SRC_COMPILER_LLVM_IR_BUILDER_H_