blob: 85506e44a9e515d6dc4cd8c79d101e231751e3ff [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"
Ian Rogers76ae4fe2013-02-27 16:03:41 -080021#include "intrinsic_helper.h"
TDYa1271f196f12012-07-11 20:50:22 -070022#include "md_builder.h"
TDYa127d668a062012-04-13 12:36:57 -070023#include "runtime_support_builder.h"
Logan Chien42e0e152012-01-13 15:42:36 +080024#include "runtime_support_func.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080025
26#include <llvm/Constants.h>
27#include <llvm/DerivedTypes.h>
TDYa127aba61122012-05-04 18:28:36 -070028#include <llvm/LLVMContext.h>
Shih-wei Liaod1fec812012-02-13 09:51:10 -080029#include <llvm/Support/IRBuilder.h>
Ian Rogers76ae4fe2013-02-27 16:03:41 -080030#include <llvm/Support/NoFolder.h>
Shih-wei Liaod1fec812012-02-13 09:51:10 -080031#include <llvm/Type.h>
32
33#include <stdint.h>
34
35
36namespace art {
37namespace compiler_llvm {
38
Ian Rogers76ae4fe2013-02-27 16:03:41 -080039class InserterWithDexOffset
40 : public llvm::IRBuilderDefaultInserter<true> {
41 public:
42 InserterWithDexOffset() : node_(NULL) {}
43 void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
44 llvm::BasicBlock *BB,
45 llvm::BasicBlock::iterator InsertPt) const {
46 llvm::IRBuilderDefaultInserter<true>::InsertHelper(I, Name, BB, InsertPt);
47 if (node_ != NULL) {
48 I->setMetadata("DexOff", node_);
49 }
50 }
51 void SetDexOffset(llvm::MDNode* node) {
52 node_ = node;
53 }
54 private:
55 llvm::MDNode* node_;
56};
Shih-wei Liaod1fec812012-02-13 09:51:10 -080057
Ian Rogers76ae4fe2013-02-27 16:03:41 -080058typedef llvm::IRBuilder<true, llvm::ConstantFolder, InserterWithDexOffset> LLVMIRBuilder;
Shih-wei Liaod1fec812012-02-13 09:51:10 -080059// NOTE: Here we define our own LLVMIRBuilder type alias, so that we can
60// switch "preserveNames" template parameter easily.
61
62
63class IRBuilder : public LLVMIRBuilder {
64 public:
65 //--------------------------------------------------------------------------
66 // General
67 //--------------------------------------------------------------------------
68
Ian Rogers76ae4fe2013-02-27 16:03:41 -080069 IRBuilder(llvm::LLVMContext& context, llvm::Module& module, IntrinsicHelper& intrinsic_helper);
Shih-wei Liaod1fec812012-02-13 09:51:10 -080070
71
72 //--------------------------------------------------------------------------
TDYa127aba61122012-05-04 18:28:36 -070073 // Extend load & store for TBAA
74 //--------------------------------------------------------------------------
75
76 llvm::LoadInst* CreateLoad(llvm::Value* ptr, llvm::MDNode* tbaa_info) {
77 llvm::LoadInst* inst = LLVMIRBuilder::CreateLoad(ptr);
78 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
79 return inst;
80 }
81
82 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, llvm::MDNode* tbaa_info) {
83 llvm::StoreInst* inst = LLVMIRBuilder::CreateStore(val, ptr);
84 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
85 return inst;
86 }
87
Sebastien Hertz50a1abf2013-02-18 14:36:41 +010088 llvm::AtomicCmpXchgInst*
89 CreateAtomicCmpXchgInst(llvm::Value* ptr, llvm::Value* cmp, llvm::Value* val,
90 llvm::MDNode* tbaa_info) {
91 llvm::AtomicCmpXchgInst* inst =
92 LLVMIRBuilder::CreateAtomicCmpXchg(ptr, cmp, val, llvm::Acquire);
93 inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_info);
94 return inst;
95 }
96
TDYa127aba61122012-05-04 18:28:36 -070097
98 //--------------------------------------------------------------------------
99 // TBAA
100 //--------------------------------------------------------------------------
101
102 // TODO: After we design the non-special TBAA info, re-design the TBAA interface.
103 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700104 return CreateLoad(ptr, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700105 }
106
107 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, TBAASpecialType special_ty) {
108 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700109 return CreateStore(val, ptr, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700110 }
111
TDYa127706e7db2012-05-06 00:05:33 -0700112 llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty, JType j_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700113 return CreateLoad(ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa127706e7db2012-05-06 00:05:33 -0700114 }
115
116 llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr,
117 TBAASpecialType special_ty, JType j_ty) {
118 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700119 return CreateStore(val, ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa127706e7db2012-05-06 00:05:33 -0700120 }
121
TDYa1278fe384d2012-05-06 20:14:17 -0700122 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
123 int64_t offset,
124 llvm::Type* type,
125 TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700126 return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700127 }
128
129 void StoreToObjectOffset(llvm::Value* object_addr,
130 int64_t offset,
131 llvm::Value* new_value,
132 TBAASpecialType special_ty) {
133 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700134 StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAASpecialType(special_ty));
TDYa127aba61122012-05-04 18:28:36 -0700135 }
136
TDYa12729c0cd12012-05-17 04:51:08 -0700137 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
138 int64_t offset,
139 llvm::Type* type,
140 TBAASpecialType special_ty, JType j_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700141 return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa12729c0cd12012-05-17 04:51:08 -0700142 }
143
144 void StoreToObjectOffset(llvm::Value* object_addr,
145 int64_t offset,
146 llvm::Value* new_value,
147 TBAASpecialType special_ty, JType j_ty) {
148 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
TDYa1271f196f12012-07-11 20:50:22 -0700149 StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
TDYa12729c0cd12012-05-17 04:51:08 -0700150 }
151
Sebastien Hertz50a1abf2013-02-18 14:36:41 +0100152 llvm::AtomicCmpXchgInst*
153 CompareExchangeObjectOffset(llvm::Value* object_addr,
154 int64_t offset,
155 llvm::Value* cmp_value,
156 llvm::Value* new_value,
157 TBAASpecialType special_ty) {
158 DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
159 return CompareExchangeObjectOffset(object_addr, offset, cmp_value, new_value,
160 mdb_.GetTBAASpecialType(special_ty));
161 }
162
TDYa127de479be2012-05-31 08:03:26 -0700163 void SetTBAA(llvm::Instruction* inst, TBAASpecialType special_ty) {
TDYa1271f196f12012-07-11 20:50:22 -0700164 inst->setMetadata(llvm::LLVMContext::MD_tbaa, mdb_.GetTBAASpecialType(special_ty));
TDYa127145d4912012-05-06 21:44:45 -0700165 }
166
TDYa127aba61122012-05-04 18:28:36 -0700167
168 //--------------------------------------------------------------------------
TDYa127ac7b5bb2012-05-11 13:17:49 -0700169 // Static Branch Prediction
170 //--------------------------------------------------------------------------
171
172 // Import the orignal conditional branch
173 using LLVMIRBuilder::CreateCondBr;
174 llvm::BranchInst* CreateCondBr(llvm::Value *cond,
175 llvm::BasicBlock* true_bb,
176 llvm::BasicBlock* false_bb,
177 ExpectCond expect) {
TDYa1271f196f12012-07-11 20:50:22 -0700178 llvm::BranchInst* branch_inst = CreateCondBr(cond, true_bb, false_bb);
179 branch_inst->setMetadata(llvm::LLVMContext::MD_prof, mdb_.GetBranchWeights(expect));
TDYa127ac7b5bb2012-05-11 13:17:49 -0700180 return branch_inst;
181 }
182
183
184 //--------------------------------------------------------------------------
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800185 // Pointer Arithmetic Helper Function
186 //--------------------------------------------------------------------------
187
188 llvm::IntegerType* getPtrEquivIntTy() {
189 return getInt32Ty();
190 }
191
192 size_t getSizeOfPtrEquivInt() {
193 return 4;
194 }
195
196 llvm::ConstantInt* getSizeOfPtrEquivIntValue() {
197 return getPtrEquivInt(getSizeOfPtrEquivInt());
198 }
199
TDYa127ee1f59b2012-04-25 00:56:40 -0700200 llvm::ConstantInt* getPtrEquivInt(int64_t i) {
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800201 return llvm::ConstantInt::get(getPtrEquivIntTy(), i);
202 }
203
204 llvm::Value* CreatePtrDisp(llvm::Value* base,
205 llvm::Value* offset,
206 llvm::PointerType* ret_ty) {
207
208 llvm::Value* base_int = CreatePtrToInt(base, getPtrEquivIntTy());
209 llvm::Value* result_int = CreateAdd(base_int, offset);
210 llvm::Value* result = CreateIntToPtr(result_int, ret_ty);
211
212 return result;
213 }
214
215 llvm::Value* CreatePtrDisp(llvm::Value* base,
216 llvm::Value* bs,
217 llvm::Value* count,
218 llvm::Value* offset,
219 llvm::PointerType* ret_ty) {
220
221 llvm::Value* block_offset = CreateMul(bs, count);
222 llvm::Value* total_offset = CreateAdd(block_offset, offset);
223
224 return CreatePtrDisp(base, total_offset, ret_ty);
225 }
226
TDYa1278fe384d2012-05-06 20:14:17 -0700227 llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
228 int64_t offset,
229 llvm::Type* type,
230 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700231 // Convert offset to llvm::value
232 llvm::Value* llvm_offset = getPtrEquivInt(offset);
233 // Calculate the value's address
234 llvm::Value* value_addr = CreatePtrDisp(object_addr, llvm_offset, type->getPointerTo());
235 // Load
TDYa127aba61122012-05-04 18:28:36 -0700236 return CreateLoad(value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700237 }
238
TDYa127aba61122012-05-04 18:28:36 -0700239 void StoreToObjectOffset(llvm::Value* object_addr,
240 int64_t offset,
241 llvm::Value* new_value,
242 llvm::MDNode* tbaa_info) {
TDYa1275bb86012012-04-11 05:57:28 -0700243 // Convert offset to llvm::value
244 llvm::Value* llvm_offset = getPtrEquivInt(offset);
245 // Calculate the value's address
246 llvm::Value* value_addr = CreatePtrDisp(object_addr,
247 llvm_offset,
248 new_value->getType()->getPointerTo());
249 // Store
TDYa127aba61122012-05-04 18:28:36 -0700250 CreateStore(new_value, value_addr, tbaa_info);
TDYa1275bb86012012-04-11 05:57:28 -0700251 }
252
Sebastien Hertz50a1abf2013-02-18 14:36:41 +0100253 llvm::AtomicCmpXchgInst* CompareExchangeObjectOffset(llvm::Value* object_addr,
254 int64_t offset,
255 llvm::Value* cmp_value,
256 llvm::Value* new_value,
257 llvm::MDNode* tbaa_info) {
258 // Convert offset to llvm::value
259 llvm::Value* llvm_offset = getPtrEquivInt(offset);
260 // Calculate the value's address
261 llvm::Value* value_addr = CreatePtrDisp(object_addr,
262 llvm_offset,
263 new_value->getType()->getPointerTo());
264 // Atomic compare and exchange
265 return CreateAtomicCmpXchgInst(value_addr, cmp_value, new_value, tbaa_info);
266 }
267
Shih-wei Liao4c1f4252012-02-13 09:57:20 -0800268
269 //--------------------------------------------------------------------------
Logan Chien42e0e152012-01-13 15:42:36 +0800270 // Runtime Helper Function
271 //--------------------------------------------------------------------------
272
TDYa127de479be2012-05-31 08:03:26 -0700273 RuntimeSupportBuilder& Runtime() {
274 return *runtime_support_;
275 }
276
277 // TODO: Deprecate
TDYa127d668a062012-04-13 12:36:57 -0700278 llvm::Function* GetRuntime(runtime_support::RuntimeId rt) {
279 return runtime_support_->GetRuntimeSupportFunction(rt);
280 }
281
TDYa127de479be2012-05-31 08:03:26 -0700282 // TODO: Deprecate
TDYa127d668a062012-04-13 12:36:57 -0700283 void SetRuntimeSupport(RuntimeSupportBuilder* runtime_support) {
284 // Can only set once. We can't do this on constructor, because RuntimeSupportBuilder needs
285 // IRBuilder.
286 if (runtime_support_ == NULL && runtime_support != NULL) {
287 runtime_support_ = runtime_support;
288 }
289 }
Logan Chien42e0e152012-01-13 15:42:36 +0800290
291
292 //--------------------------------------------------------------------------
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800293 // Type Helper Function
294 //--------------------------------------------------------------------------
295
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800296 llvm::Type* getJType(char shorty_jty) {
297 return getJType(GetJTypeFromShorty(shorty_jty));
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800298 }
299
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800300 llvm::Type* getJType(JType jty);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800301
302 llvm::Type* getJVoidTy() {
303 return getVoidTy();
304 }
305
306 llvm::IntegerType* getJBooleanTy() {
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800307 return getInt8Ty();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800308 }
309
310 llvm::IntegerType* getJByteTy() {
311 return getInt8Ty();
312 }
313
314 llvm::IntegerType* getJCharTy() {
315 return getInt16Ty();
316 }
317
318 llvm::IntegerType* getJShortTy() {
319 return getInt16Ty();
320 }
321
322 llvm::IntegerType* getJIntTy() {
323 return getInt32Ty();
324 }
325
326 llvm::IntegerType* getJLongTy() {
327 return getInt64Ty();
328 }
329
330 llvm::Type* getJFloatTy() {
331 return getFloatTy();
332 }
333
334 llvm::Type* getJDoubleTy() {
335 return getDoubleTy();
336 }
337
338 llvm::PointerType* getJObjectTy() {
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800339 return java_object_type_;
340 }
341
342 llvm::PointerType* getJMethodTy() {
343 return java_method_type_;
344 }
345
346 llvm::PointerType* getJThreadTy() {
347 return java_thread_type_;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800348 }
349
TDYa1270de52be2012-05-27 20:49:31 -0700350 llvm::Type* getArtFrameTy() {
351 return art_frame_type_;
352 }
353
Logan Chienf04364f2012-02-10 12:01:39 +0800354 llvm::PointerType* getJEnvTy() {
355 return jenv_type_;
356 }
357
358 llvm::Type* getJValueTy() {
359 // NOTE: JValue is an union type, which may contains boolean, byte, char,
360 // short, int, long, float, double, Object. However, LLVM itself does
361 // not support union type, so we have to return a type with biggest size,
362 // then bitcast it before we use it.
363 return getJLongTy();
364 }
365
TDYa127ce4cc0d2012-11-18 16:59:53 -0800366 llvm::StructType* getShadowFrameTy(uint32_t vreg_size);
Logan Chien8dfcbea2012-02-17 18:50:32 +0800367
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800368
369 //--------------------------------------------------------------------------
370 // Constant Value Helper Function
371 //--------------------------------------------------------------------------
372
373 llvm::ConstantInt* getJBoolean(bool is_true) {
374 return (is_true) ? getTrue() : getFalse();
375 }
376
377 llvm::ConstantInt* getJByte(int8_t i) {
378 return llvm::ConstantInt::getSigned(getJByteTy(), i);
379 }
380
381 llvm::ConstantInt* getJChar(int16_t i) {
382 return llvm::ConstantInt::getSigned(getJCharTy(), i);
383 }
384
385 llvm::ConstantInt* getJShort(int16_t i) {
386 return llvm::ConstantInt::getSigned(getJShortTy(), i);
387 }
388
389 llvm::ConstantInt* getJInt(int32_t i) {
390 return llvm::ConstantInt::getSigned(getJIntTy(), i);
391 }
392
393 llvm::ConstantInt* getJLong(int64_t i) {
394 return llvm::ConstantInt::getSigned(getJLongTy(), i);
395 }
396
397 llvm::Constant* getJFloat(float f) {
398 return llvm::ConstantFP::get(getJFloatTy(), f);
399 }
400
401 llvm::Constant* getJDouble(double d) {
402 return llvm::ConstantFP::get(getJDoubleTy(), d);
403 }
404
405 llvm::ConstantPointerNull* getJNull() {
406 return llvm::ConstantPointerNull::get(getJObjectTy());
407 }
408
409 llvm::Constant* getJZero(char shorty_jty) {
410 return getJZero(GetJTypeFromShorty(shorty_jty));
411 }
412
413 llvm::Constant* getJZero(JType jty) {
414 switch (jty) {
415 case kVoid:
Logan Chien83426162011-12-09 09:29:50 +0800416 LOG(FATAL) << "Zero is not a value of void type";
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800417 return NULL;
418
419 case kBoolean:
420 return getJBoolean(false);
421
422 case kByte:
423 return getJByte(0);
424
425 case kChar:
426 return getJChar(0);
427
428 case kShort:
429 return getJShort(0);
430
431 case kInt:
432 return getJInt(0);
433
434 case kLong:
435 return getJLong(0);
436
437 case kFloat:
438 return getJFloat(0.0f);
439
440 case kDouble:
441 return getJDouble(0.0);
442
443 case kObject:
444 return getJNull();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800445
TDYa127706e7db2012-05-06 00:05:33 -0700446 default:
447 LOG(FATAL) << "Unknown java type: " << jty;
448 return NULL;
449 }
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800450 }
451
452
453 private:
Logan Chien6a917992012-02-17 18:43:48 +0800454 llvm::Module* module_;
455
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800456 MDBuilder mdb_;
457
458 llvm::PointerType* java_object_type_;
459 llvm::PointerType* java_method_type_;
460 llvm::PointerType* java_thread_type_;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800461
Logan Chienf04364f2012-02-10 12:01:39 +0800462 llvm::PointerType* jenv_type_;
463
Logan Chien8dfcbea2012-02-17 18:50:32 +0800464 llvm::StructType* art_frame_type_;
465
TDYa127d668a062012-04-13 12:36:57 -0700466 RuntimeSupportBuilder* runtime_support_;
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800467
468 IntrinsicHelper& intrinsic_helper_;
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800469};
470
471
472} // namespace compiler_llvm
473} // namespace art
474
475#endif // ART_SRC_COMPILER_LLVM_IR_BUILDER_H_