blob: e722c683a54532f85466c00784c7bdc5dd25e3f6 [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"
Sebastien Hertz0d43d542013-02-27 19:02:16 +010021#include "compiler/dex/compiler_enums.h"
Ian Rogers76ae4fe2013-02-27 16:03:41 -080022#include "intrinsic_helper.h"
TDYa1271f196f12012-07-11 20:50:22 -070023#include "md_builder.h"
TDYa127d668a062012-04-13 12:36:57 -070024#include "runtime_support_builder.h"
Logan Chien42e0e152012-01-13 15:42:36 +080025#include "runtime_support_func.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080026
27#include <llvm/Constants.h>
28#include <llvm/DerivedTypes.h>
TDYa127aba61122012-05-04 18:28:36 -070029#include <llvm/LLVMContext.h>
Shih-wei Liaod1fec812012-02-13 09:51:10 -080030#include <llvm/Support/IRBuilder.h>
Ian Rogers76ae4fe2013-02-27 16:03:41 -080031#include <llvm/Support/NoFolder.h>
Shih-wei Liaod1fec812012-02-13 09:51:10 -080032#include <llvm/Type.h>
33
34#include <stdint.h>
35
36
37namespace art {
38namespace compiler_llvm {
39
Ian Rogers76ae4fe2013-02-27 16:03:41 -080040class InserterWithDexOffset
41 : public llvm::IRBuilderDefaultInserter<true> {
42 public:
43 InserterWithDexOffset() : node_(NULL) {}
44 void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
45 llvm::BasicBlock *BB,
46 llvm::BasicBlock::iterator InsertPt) const {
47 llvm::IRBuilderDefaultInserter<true>::InsertHelper(I, Name, BB, InsertPt);
48 if (node_ != NULL) {
49 I->setMetadata("DexOff", node_);
50 }
51 }
52 void SetDexOffset(llvm::MDNode* node) {
53 node_ = node;
54 }
55 private:
56 llvm::MDNode* node_;
57};
Shih-wei Liaod1fec812012-02-13 09:51:10 -080058
Ian Rogers76ae4fe2013-02-27 16:03:41 -080059typedef llvm::IRBuilder<true, llvm::ConstantFolder, InserterWithDexOffset> LLVMIRBuilder;
Shih-wei Liaod1fec812012-02-13 09:51:10 -080060// NOTE: Here we define our own LLVMIRBuilder type alias, so that we can
61// switch "preserveNames" template parameter easily.
62
63
64class IRBuilder : public LLVMIRBuilder {
65 public:
66 //--------------------------------------------------------------------------
67 // General
68 //--------------------------------------------------------------------------
69
Ian Rogers76ae4fe2013-02-27 16:03:41 -080070 IRBuilder(llvm::LLVMContext& context, llvm::Module& module, IntrinsicHelper& intrinsic_helper);
Shih-wei Liaod1fec812012-02-13 09:51:10 -080071
72
73 //--------------------------------------------------------------------------
TDYa127aba61122012-05-04 18:28:36 -070074 // Extend load & store for TBAA
75 //--------------------------------------------------------------------------
76
77 llvm::LoadInst* CreateLoad(llvm::Value* ptr, llvm::MDNode* tbaa_info) {
78 llvm::LoadInst* inst = LLVMIRBuilder::CreateLoad(ptr);
79 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
80 return inst;
81 }
82
83 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, llvm::MDNode* tbaa_info) {
84 llvm::StoreInst* inst = LLVMIRBuilder::CreateStore(val, ptr);
85 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
86 return inst;
87 }
88
Sebastien Hertz50a1abf2013-02-18 14:36:41 +010089 llvm::AtomicCmpXchgInst*
90 CreateAtomicCmpXchgInst(llvm::Value* ptr, llvm::Value* cmp, llvm::Value* val,
91 llvm::MDNode* tbaa_info) {
92 llvm::AtomicCmpXchgInst* inst =
93 LLVMIRBuilder::CreateAtomicCmpXchg(ptr, cmp, val, llvm::Acquire);
94 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
95 return inst;
96 }
97
Sebastien Hertz0d43d542013-02-27 19:02:16 +010098 //--------------------------------------------------------------------------
99 // Extend memory barrier
100 //--------------------------------------------------------------------------
101 void CreateMemoryBarrier(MemBarrierKind barrier_kind) {
102#if ANDROID_SMP
103 // TODO: select atomic ordering according to given barrier kind.
104 CreateFence(llvm::SequentiallyConsistent);
105#endif
106 }
TDYa127aba61122012-05-04 18:28:36 -0700107
108 //--------------------------------------------------------------------------
109 // TBAA
110 //--------------------------------------------------------------------------
111
112 // TODO: After we design the non-special TBAA info, re-design the TBAA interface.
113 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700114 return CreateLoad(ptr, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700115 }
116
117 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, TBAASpecialType special_ty) {
118 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700119 return CreateStore(val, ptr, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700120 }
121
TDYa127706e7db2012-05-06 00:05:33 -0700122 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty, JType j_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700123 return CreateLoad(ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa127706e7db2012-05-06 00:05:33 -0700124 }
125
126 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr,
127 TBAASpecialType special_ty, JType j_ty) {
128 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700129 return CreateStore(val, ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa127706e7db2012-05-06 00:05:33 -0700130 }
131
TDYa1278fe384d2012-05-06 20:14:17 -0700132 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
133 int64_t offset,
134 llvm::Type* type,
135 TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700136 return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700137 }
138
139 void StoreToObjectOffset(llvm::Value* object_addr,
140 int64_t offset,
141 llvm::Value* new_value,
142 TBAASpecialType special_ty) {
143 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700144 StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700145 }
146
TDYa12729c0cd12012-05-17 04:51:08 -0700147 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
148 int64_t offset,
149 llvm::Type* type,
150 TBAASpecialType special_ty, JType j_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700151 return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa12729c0cd12012-05-17 04:51:08 -0700152 }
153
154 void StoreToObjectOffset(llvm::Value* object_addr,
155 int64_t offset,
156 llvm::Value* new_value,
157 TBAASpecialType special_ty, JType j_ty) {
158 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700159 StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa12729c0cd12012-05-17 04:51:08 -0700160 }
161
Sebastien Hertz50a1abf2013-02-18 14:36:41 +0100162 llvm::AtomicCmpXchgInst*
163 CompareExchangeObjectOffset(llvm::Value* object_addr,
164 int64_t offset,
165 llvm::Value* cmp_value,
166 llvm::Value* new_value,
167 TBAASpecialType special_ty) {
168 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
169 return CompareExchangeObjectOffset(object_addr, offset, cmp_value, new_value,
170 mdb_.GetTBAASpecialType(special_ty));
171 }
172
TDYa127de479be2012-05-31 08:03:26 -0700173 void SetTBAA(llvm::Instruction* inst, TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700174 inst->setMetadata(llvm::LLVMContext::MD_tbaa, mdb_.GetTBAASpecialType(special_ty));
TDYa127145d4912012-05-06 21:44:45 -0700175 }
176
TDYa127aba61122012-05-04 18:28:36 -0700177
178 //--------------------------------------------------------------------------
TDYa127ac7b5bb2012-05-11 13:17:49 -0700179 // Static Branch Prediction
180 //--------------------------------------------------------------------------
181
182 // Import the orignal conditional branch
183 using LLVMIRBuilder::CreateCondBr;
184 llvm::BranchInst* CreateCondBr(llvm::Value *cond,
185 llvm::BasicBlock* true_bb,
186 llvm::BasicBlock* false_bb,
187 ExpectCond expect) {
TDYa1271f196f12012-07-11 20:50:22 -0700188 llvm::BranchInst* branch_inst = CreateCondBr(cond, true_bb, false_bb);
189 branch_inst->setMetadata(llvm::LLVMContext::MD_prof, mdb_.GetBranchWeights(expect));
TDYa127ac7b5bb2012-05-11 13:17:49 -0700190 return branch_inst;
191 }
192
193
194 //--------------------------------------------------------------------------
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800195 // Pointer Arithmetic Helper Function
196 //--------------------------------------------------------------------------
197
198 llvm::IntegerType* getPtrEquivIntTy() {
199 return getInt32Ty();
200 }
201
202 size_t getSizeOfPtrEquivInt() {
203 return 4;
204 }
205
206 llvm::ConstantInt* getSizeOfPtrEquivIntValue() {
207 return getPtrEquivInt(getSizeOfPtrEquivInt());
208 }
209
TDYa127ee1f59b2012-04-25 00:56:40 -0700210 llvm::ConstantInt* getPtrEquivInt(int64_t i) {
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800211 return llvm::ConstantInt::get(getPtrEquivIntTy(), i);
212 }
213
214 llvm::Value* CreatePtrDisp(llvm::Value* base,
215 llvm::Value* offset,
216 llvm::PointerType* ret_ty) {
217
218 llvm::Value* base_int = CreatePtrToInt(base, getPtrEquivIntTy());
219 llvm::Value* result_int = CreateAdd(base_int, offset);
220 llvm::Value* result = CreateIntToPtr(result_int, ret_ty);
221
222 return result;
223 }
224
225 llvm::Value* CreatePtrDisp(llvm::Value* base,
226 llvm::Value* bs,
227 llvm::Value* count,
228 llvm::Value* offset,
229 llvm::PointerType* ret_ty) {
230
231 llvm::Value* block_offset = CreateMul(bs, count);
232 llvm::Value* total_offset = CreateAdd(block_offset, offset);
233
234 return CreatePtrDisp(base, total_offset, ret_ty);
235 }
236
TDYa1278fe384d2012-05-06 20:14:17 -0700237 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
238 int64_t offset,
239 llvm::Type* type,
240 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700241 // Convert offset to llvm::value
242 llvm::Value* llvm_offset = getPtrEquivInt(offset);
243 // Calculate the value's address
244 llvm::Value* value_addr = CreatePtrDisp(object_addr, llvm_offset, type->getPointerTo());
245 // Load
TDYa127aba61122012-05-04 18:28:36 -0700246 return CreateLoad(value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700247 }
248
TDYa127aba61122012-05-04 18:28:36 -0700249 void StoreToObjectOffset(llvm::Value* object_addr,
250 int64_t offset,
251 llvm::Value* new_value,
252 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700253 // Convert offset to llvm::value
254 llvm::Value* llvm_offset = getPtrEquivInt(offset);
255 // Calculate the value's address
256 llvm::Value* value_addr = CreatePtrDisp(object_addr,
257 llvm_offset,
258 new_value->getType()->getPointerTo());
259 // Store
TDYa127aba61122012-05-04 18:28:36 -0700260 CreateStore(new_value, value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700261 }
262
Sebastien Hertz50a1abf2013-02-18 14:36:41 +0100263 llvm::AtomicCmpXchgInst* CompareExchangeObjectOffset(llvm::Value* object_addr,
264 int64_t offset,
265 llvm::Value* cmp_value,
266 llvm::Value* new_value,
267 llvm::MDNode* tbaa_info) {
268 // Convert offset to llvm::value
269 llvm::Value* llvm_offset = getPtrEquivInt(offset);
270 // Calculate the value's address
271 llvm::Value* value_addr = CreatePtrDisp(object_addr,
272 llvm_offset,
273 new_value->getType()->getPointerTo());
274 // Atomic compare and exchange
275 return CreateAtomicCmpXchgInst(value_addr, cmp_value, new_value, tbaa_info);
276 }
277
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800278
279 //--------------------------------------------------------------------------
Logan Chien42e0e152012-01-13 15:42:36 +0800280 // Runtime Helper Function
281 //--------------------------------------------------------------------------
282
TDYa127de479be2012-05-31 08:03:26 -0700283 RuntimeSupportBuilder& Runtime() {
284 return *runtime_support_;
285 }
286
287 // TODO: Deprecate
TDYa127d668a062012-04-13 12:36:57 -0700288 llvm::Function* GetRuntime(runtime_support::RuntimeId rt) {
289 return runtime_support_->GetRuntimeSupportFunction(rt);
290 }
291
TDYa127de479be2012-05-31 08:03:26 -0700292 // TODO: Deprecate
TDYa127d668a062012-04-13 12:36:57 -0700293 void SetRuntimeSupport(RuntimeSupportBuilder* runtime_support) {
294 // Can only set once. We can't do this on constructor, because RuntimeSupportBuilder needs
295 // IRBuilder.
296 if (runtime_support_ == NULL && runtime_support != NULL) {
297 runtime_support_ = runtime_support;
298 }
299 }
Logan Chien42e0e152012-01-13 15:42:36 +0800300
301
302 //--------------------------------------------------------------------------
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800303 // Type Helper Function
304 //--------------------------------------------------------------------------
305
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800306 llvm::Type* getJType(char shorty_jty) {
307 return getJType(GetJTypeFromShorty(shorty_jty));
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800308 }
309
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800310 llvm::Type* getJType(JType jty);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800311
312 llvm::Type* getJVoidTy() {
313 return getVoidTy();
314 }
315
316 llvm::IntegerType* getJBooleanTy() {
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800317 return getInt8Ty();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800318 }
319
320 llvm::IntegerType* getJByteTy() {
321 return getInt8Ty();
322 }
323
324 llvm::IntegerType* getJCharTy() {
325 return getInt16Ty();
326 }
327
328 llvm::IntegerType* getJShortTy() {
329 return getInt16Ty();
330 }
331
332 llvm::IntegerType* getJIntTy() {
333 return getInt32Ty();
334 }
335
336 llvm::IntegerType* getJLongTy() {
337 return getInt64Ty();
338 }
339
340 llvm::Type* getJFloatTy() {
341 return getFloatTy();
342 }
343
344 llvm::Type* getJDoubleTy() {
345 return getDoubleTy();
346 }
347
348 llvm::PointerType* getJObjectTy() {
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800349 return java_object_type_;
350 }
351
352 llvm::PointerType* getJMethodTy() {
353 return java_method_type_;
354 }
355
356 llvm::PointerType* getJThreadTy() {
357 return java_thread_type_;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800358 }
359
TDYa1270de52be2012-05-27 20:49:31 -0700360 llvm::Type* getArtFrameTy() {
361 return art_frame_type_;
362 }
363
Logan Chienf04364f2012-02-10 12:01:39 +0800364 llvm::PointerType* getJEnvTy() {
365 return jenv_type_;
366 }
367
368 llvm::Type* getJValueTy() {
369 // NOTE: JValue is an union type, which may contains boolean, byte, char,
370 // short, int, long, float, double, Object. However, LLVM itself does
371 // not support union type, so we have to return a type with biggest size,
372 // then bitcast it before we use it.
373 return getJLongTy();
374 }
375
TDYa127ce4cc0d2012-11-18 16:59:53 -0800376 llvm::StructType* getShadowFrameTy(uint32_t vreg_size);
Logan Chien8dfcbea2012-02-17 18:50:32 +0800377
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800378
379 //--------------------------------------------------------------------------
380 // Constant Value Helper Function
381 //--------------------------------------------------------------------------
382
383 llvm::ConstantInt* getJBoolean(bool is_true) {
384 return (is_true) ? getTrue() : getFalse();
385 }
386
387 llvm::ConstantInt* getJByte(int8_t i) {
388 return llvm::ConstantInt::getSigned(getJByteTy(), i);
389 }
390
391 llvm::ConstantInt* getJChar(int16_t i) {
392 return llvm::ConstantInt::getSigned(getJCharTy(), i);
393 }
394
395 llvm::ConstantInt* getJShort(int16_t i) {
396 return llvm::ConstantInt::getSigned(getJShortTy(), i);
397 }
398
399 llvm::ConstantInt* getJInt(int32_t i) {
400 return llvm::ConstantInt::getSigned(getJIntTy(), i);
401 }
402
403 llvm::ConstantInt* getJLong(int64_t i) {
404 return llvm::ConstantInt::getSigned(getJLongTy(), i);
405 }
406
407 llvm::Constant* getJFloat(float f) {
408 return llvm::ConstantFP::get(getJFloatTy(), f);
409 }
410
411 llvm::Constant* getJDouble(double d) {
412 return llvm::ConstantFP::get(getJDoubleTy(), d);
413 }
414
415 llvm::ConstantPointerNull* getJNull() {
416 return llvm::ConstantPointerNull::get(getJObjectTy());
417 }
418
419 llvm::Constant* getJZero(char shorty_jty) {
420 return getJZero(GetJTypeFromShorty(shorty_jty));
421 }
422
423 llvm::Constant* getJZero(JType jty) {
424 switch (jty) {
425 case kVoid:
Logan Chien83426162011-12-09 09:29:50 +0800426 LOG(FATAL) << "Zero is not a value of void type";
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800427 return NULL;
428
429 case kBoolean:
430 return getJBoolean(false);
431
432 case kByte:
433 return getJByte(0);
434
435 case kChar:
436 return getJChar(0);
437
438 case kShort:
439 return getJShort(0);
440
441 case kInt:
442 return getJInt(0);
443
444 case kLong:
445 return getJLong(0);
446
447 case kFloat:
448 return getJFloat(0.0f);
449
450 case kDouble:
451 return getJDouble(0.0);
452
453 case kObject:
454 return getJNull();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800455
TDYa127706e7db2012-05-06 00:05:33 -0700456 default:
457 LOG(FATAL) << "Unknown java type: " << jty;
458 return NULL;
459 }
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800460 }
461
462
463 private:
Logan Chien6a917992012-02-17 18:43:48 +0800464 llvm::Module* module_;
465
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800466 MDBuilder mdb_;
467
468 llvm::PointerType* java_object_type_;
469 llvm::PointerType* java_method_type_;
470 llvm::PointerType* java_thread_type_;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800471
Logan Chienf04364f2012-02-10 12:01:39 +0800472 llvm::PointerType* jenv_type_;
473
Logan Chien8dfcbea2012-02-17 18:50:32 +0800474 llvm::StructType* art_frame_type_;
475
TDYa127d668a062012-04-13 12:36:57 -0700476 RuntimeSupportBuilder* runtime_support_;
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800477
478 IntrinsicHelper& intrinsic_helper_;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800479};
480
481
482} // namespace compiler_llvm
483} // namespace art
484
485#endif // ART_SRC_COMPILER_LLVM_IR_BUILDER_H_