Mercurial > projects > ldc
comparison gen/tollvm.cpp @ 213:7816aafeea3c trunk
[svn r229] Updated the object.d implementation to the latest Tango.
Fixed a bunch of the built-in typeinfos for arrays, they did not inherit TypeInfo_Array.
Applied patch to tango/text/convert/Layout.d by fvbommel, closes #47 .
Cleaned up some type code.
Replaced uses of llvm::Type with LLType (a typedef), same for Value and Constant.
Fixed a few cases where typeinfo for user structs could be emitted multiple times, seems to still be some cases of this :/
author | lindquist |
---|---|
date | Fri, 30 May 2008 19:32:04 +0200 |
parents | 1d6cfdbc97f0 |
children | 0806379a5eca |
comparison
equal
deleted
inserted
replaced
212:4c2689d57ba4 | 213:7816aafeea3c |
---|---|
34 return DtoDType(bt); | 34 return DtoDType(bt); |
35 } | 35 } |
36 return t; | 36 return t; |
37 } | 37 } |
38 | 38 |
39 const llvm::Type* DtoType(Type* t) | 39 const LLType* DtoType(Type* t) |
40 { | 40 { |
41 assert(t); | 41 assert(t); |
42 switch (t->ty) | 42 switch (t->ty) |
43 { | 43 { |
44 // integers | 44 // integers |
45 case Tint8: | 45 case Tint8: |
46 case Tuns8: | 46 case Tuns8: |
47 case Tchar: | 47 case Tchar: |
48 return (const llvm::Type*)llvm::Type::Int8Ty; | 48 return (const LLType*)llvm::Type::Int8Ty; |
49 case Tint16: | 49 case Tint16: |
50 case Tuns16: | 50 case Tuns16: |
51 case Twchar: | 51 case Twchar: |
52 return (const llvm::Type*)llvm::Type::Int16Ty; | 52 return (const LLType*)llvm::Type::Int16Ty; |
53 case Tint32: | 53 case Tint32: |
54 case Tuns32: | 54 case Tuns32: |
55 case Tdchar: | 55 case Tdchar: |
56 return (const llvm::Type*)llvm::Type::Int32Ty; | 56 return (const LLType*)llvm::Type::Int32Ty; |
57 case Tint64: | 57 case Tint64: |
58 case Tuns64: | 58 case Tuns64: |
59 return (const llvm::Type*)llvm::Type::Int64Ty; | 59 return (const LLType*)llvm::Type::Int64Ty; |
60 | 60 |
61 case Tbool: | 61 case Tbool: |
62 return (const llvm::Type*)llvm::ConstantInt::getTrue()->getType(); | 62 return (const LLType*)llvm::ConstantInt::getTrue()->getType(); |
63 | 63 |
64 // floats | 64 // floats |
65 case Tfloat32: | 65 case Tfloat32: |
66 case Timaginary32: | 66 case Timaginary32: |
67 return llvm::Type::FloatTy; | 67 return llvm::Type::FloatTy; |
79 | 79 |
80 // pointers | 80 // pointers |
81 case Tpointer: { | 81 case Tpointer: { |
82 assert(t->next); | 82 assert(t->next); |
83 if (t->next->ty == Tvoid) | 83 if (t->next->ty == Tvoid) |
84 return (const llvm::Type*)getPtrToType(llvm::Type::Int8Ty); | 84 return (const LLType*)getPtrToType(llvm::Type::Int8Ty); |
85 else | 85 else |
86 return (const llvm::Type*)getPtrToType(DtoType(t->next)); | 86 return (const LLType*)getPtrToType(DtoType(t->next)); |
87 } | 87 } |
88 | 88 |
89 // arrays | 89 // arrays |
90 case Tarray: | 90 case Tarray: |
91 return DtoArrayType(t); | 91 return DtoArrayType(t); |
176 | 176 |
177 // associative arrays | 177 // associative arrays |
178 case Taarray: | 178 case Taarray: |
179 { | 179 { |
180 TypeAArray* taa = (TypeAArray*)t; | 180 TypeAArray* taa = (TypeAArray*)t; |
181 std::vector<const llvm::Type*> types; | 181 std::vector<const LLType*> types; |
182 types.push_back(DtoType(taa->key)); | 182 types.push_back(DtoType(taa->key)); |
183 types.push_back(DtoType(taa->next)); | 183 types.push_back(DtoType(taa->next)); |
184 return getPtrToType(llvm::StructType::get(types)); | 184 return getPtrToType(llvm::StructType::get(types)); |
185 } | 185 } |
186 | 186 |
193 | 193 |
194 ////////////////////////////////////////////////////////////////////////////////////////// | 194 ////////////////////////////////////////////////////////////////////////////////////////// |
195 | 195 |
196 const llvm::StructType* DtoDelegateType(Type* t) | 196 const llvm::StructType* DtoDelegateType(Type* t) |
197 { | 197 { |
198 const llvm::Type* i8ptr = getPtrToType(llvm::Type::Int8Ty); | 198 const LLType* i8ptr = getPtrToType(llvm::Type::Int8Ty); |
199 const llvm::Type* func = DtoFunctionType(t->next, i8ptr); | 199 const LLType* func = DtoFunctionType(t->next, i8ptr); |
200 const llvm::Type* funcptr = getPtrToType(func); | 200 const LLType* funcptr = getPtrToType(func); |
201 | 201 |
202 std::vector<const llvm::Type*> types; | 202 std::vector<const LLType*> types; |
203 types.push_back(i8ptr); | 203 types.push_back(i8ptr); |
204 types.push_back(funcptr); | 204 types.push_back(funcptr); |
205 return llvm::StructType::get(types); | 205 return llvm::StructType::get(types); |
206 } | 206 } |
207 | 207 |
208 ////////////////////////////////////////////////////////////////////////////////////////// | 208 ////////////////////////////////////////////////////////////////////////////////////////// |
209 | 209 |
210 /* | |
210 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false) | 211 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false) |
211 { | 212 { |
212 assert(bits == 32 || bits == 64); | 213 assert(bits == 32 || bits == 64); |
213 const llvm::Type* int8ty = (const llvm::Type*)llvm::Type::Int8Ty; | 214 const LLType* int8ty = (const LLType*)llvm::Type::Int8Ty; |
214 const llvm::Type* int32ty = (const llvm::Type*)llvm::Type::Int32Ty; | 215 const LLType* int32ty = (const LLType*)llvm::Type::Int32Ty; |
215 const llvm::Type* int64ty = (const llvm::Type*)llvm::Type::Int64Ty; | 216 const LLType* int64ty = (const LLType*)llvm::Type::Int64Ty; |
216 const llvm::Type* int8ptrty = (const llvm::Type*)getPtrToType(llvm::Type::Int8Ty); | 217 const LLType* int8ptrty = (const LLType*)getPtrToType(llvm::Type::Int8Ty); |
217 const llvm::Type* voidty = (const llvm::Type*)llvm::Type::VoidTy; | 218 const LLType* voidty = (const LLType*)llvm::Type::VoidTy; |
218 | 219 |
219 assert(gIR); | 220 assert(gIR); |
220 assert(gIR->module); | 221 assert(gIR->module); |
221 | 222 |
222 // parameter types | 223 // parameter types |
223 std::vector<const llvm::Type*> pvec; | 224 std::vector<const LLType*> pvec; |
224 pvec.push_back(int8ptrty); | 225 pvec.push_back(int8ptrty); |
225 pvec.push_back(set?int8ty:int8ptrty); | 226 pvec.push_back(set?int8ty:int8ptrty); |
226 pvec.push_back(bits==32?int32ty:int64ty); | 227 pvec.push_back(bits==32?int32ty:int64ty); |
227 pvec.push_back(int32ty); | 228 pvec.push_back(int32ty); |
228 llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false); | 229 llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false); |
229 return llvm::cast<llvm::Function>(gIR->module->getOrInsertFunction(name, functype)); | 230 return llvm::cast<llvm::Function>(gIR->module->getOrInsertFunction(name, functype)); |
230 } | 231 } |
232 */ | |
231 | 233 |
232 ////////////////////////////////////////////////////////////////////////////////////////// | 234 ////////////////////////////////////////////////////////////////////////////////////////// |
233 | 235 |
234 // llvm.memset.i32 | 236 // llvm.memset.i32 |
235 llvm::Function* LLVM_DeclareMemSet32() | 237 llvm::Function* LLVM_DeclareMemSet32() |
236 { | 238 { |
237 if (gIR->llvm_DeclareMemSet32 == 0) { | 239 return GET_INTRINSIC_DECL(memset_i32); |
238 gIR->llvm_DeclareMemSet32 = LLVM_DeclareMemIntrinsic("llvm.memset.i32", 32, true); | |
239 } | |
240 return gIR->llvm_DeclareMemSet32; | |
241 } | 240 } |
242 | 241 |
243 ////////////////////////////////////////////////////////////////////////////////////////// | 242 ////////////////////////////////////////////////////////////////////////////////////////// |
244 | 243 |
245 llvm::Function* LLVM_DeclareMemSet64() | 244 llvm::Function* LLVM_DeclareMemSet64() |
246 { | 245 { |
247 if (gIR->llvm_DeclareMemSet64 == 0) { | 246 return GET_INTRINSIC_DECL(memset_i64); |
248 gIR->llvm_DeclareMemSet64 = LLVM_DeclareMemIntrinsic("llvm.memset.i64", 64, true); | |
249 } | |
250 return gIR->llvm_DeclareMemSet64; | |
251 } | 247 } |
252 | 248 |
253 ////////////////////////////////////////////////////////////////////////////////////////// | 249 ////////////////////////////////////////////////////////////////////////////////////////// |
254 | 250 |
255 // llvm.memcpy.i32 | 251 // llvm.memcpy.i32 |
256 llvm::Function* LLVM_DeclareMemCpy32() | 252 llvm::Function* LLVM_DeclareMemCpy32() |
257 { | 253 { |
258 if (gIR->llvm_DeclareMemCpy32 == 0) { | 254 return GET_INTRINSIC_DECL(memcpy_i32); |
259 gIR->llvm_DeclareMemCpy32 = LLVM_DeclareMemIntrinsic("llvm.memcpy.i32", 32); | |
260 } | |
261 return gIR->llvm_DeclareMemCpy32; | |
262 } | 255 } |
263 | 256 |
264 ////////////////////////////////////////////////////////////////////////////////////////// | 257 ////////////////////////////////////////////////////////////////////////////////////////// |
265 | 258 |
266 // llvm.memcpy.i64 | 259 // llvm.memcpy.i64 |
267 llvm::Function* LLVM_DeclareMemCpy64() | 260 llvm::Function* LLVM_DeclareMemCpy64() |
268 { | 261 { |
269 if (gIR->llvm_DeclareMemCpy64 == 0) { | 262 return GET_INTRINSIC_DECL(memcpy_i64); |
270 gIR->llvm_DeclareMemCpy64 = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64); | |
271 } | |
272 return gIR->llvm_DeclareMemCpy64; | |
273 } | |
274 | |
275 // llvm.memory.barrier | |
276 static llvm::Function* LLVM_DeclareMemBarrier() | |
277 { | |
278 if (gIR->llvm_DeclareMemBarrier == 0) { | |
279 std::vector<const llvm::Type*> pvec; | |
280 pvec.push_back(llvm::Type::Int1Ty); | |
281 pvec.push_back(llvm::Type::Int1Ty); | |
282 pvec.push_back(llvm::Type::Int1Ty); | |
283 pvec.push_back(llvm::Type::Int1Ty); | |
284 pvec.push_back(llvm::Type::Int1Ty); | |
285 llvm::FunctionType* functype = llvm::FunctionType::get(llvm::Type::VoidTy, pvec, false); | |
286 gIR->llvm_DeclareMemBarrier = llvm::cast<llvm::Function>(gIR->module->getOrInsertFunction("llvm.memory.barrier", functype)); | |
287 assert(gIR->llvm_DeclareMemBarrier != NULL); | |
288 } | |
289 return gIR->llvm_DeclareMemBarrier; | |
290 } | 263 } |
291 | 264 |
292 void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device) | 265 void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device) |
293 { | 266 { |
294 llvm::Function* fn = LLVM_DeclareMemBarrier(); | 267 llvm::Function* fn = GET_INTRINSIC_DECL(memory_barrier); |
295 assert(fn != NULL); | 268 assert(fn != NULL); |
296 | 269 |
297 llvm::SmallVector<llvm::Value*, 5> llargs; | 270 LLSmallVector<LLValue*, 5> llargs; |
298 llargs.push_back(DtoConstBool(ll)); | 271 llargs.push_back(DtoConstBool(ll)); |
299 llargs.push_back(DtoConstBool(ls)); | 272 llargs.push_back(DtoConstBool(ls)); |
300 llargs.push_back(DtoConstBool(sl)); | 273 llargs.push_back(DtoConstBool(sl)); |
301 llargs.push_back(DtoConstBool(ss)); | 274 llargs.push_back(DtoConstBool(ss)); |
302 llargs.push_back(DtoConstBool(device)); | 275 llargs.push_back(DtoConstBool(device)); |
304 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 277 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
305 } | 278 } |
306 | 279 |
307 ////////////////////////////////////////////////////////////////////////////////////////// | 280 ////////////////////////////////////////////////////////////////////////////////////////// |
308 | 281 |
309 llvm::Value* DtoDelegateToNull(llvm::Value* v) | 282 void DtoDelegateToNull(LLValue* v) |
310 { | 283 { |
311 assert(gIR); | 284 LLSmallVector<LLValue*, 4> args; |
312 d_uns64 n = (global.params.is64bit) ? 16 : 8; | 285 args.push_back(DtoBitCast(v, getVoidPtrType())); |
313 | 286 args.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty)); |
314 const llvm::Type* i8p_ty = getPtrToType(llvm::Type::Int8Ty); | 287 args.push_back(DtoConstInt(global.params.is64bit ? 16 : 8)); |
315 | 288 args.push_back(DtoConstInt(0)); |
316 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb()); | 289 gIR->ir->CreateCall(GET_INTRINSIC_DECL(memset_i32), args.begin(), args.end(), ""); |
317 | 290 } |
318 llvm::Function* fn = LLVM_DeclareMemSet32(); | 291 |
319 std::vector<llvm::Value*> llargs; | 292 ////////////////////////////////////////////////////////////////////////////////////////// |
320 llargs.resize(4); | 293 |
321 llargs[0] = arr; | 294 void DtoDelegateCopy(LLValue* dst, LLValue* src) |
322 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | 295 { |
323 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | 296 LLSmallVector<LLValue*, 4> args; |
324 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 297 args.push_back(DtoBitCast(dst,getVoidPtrType())); |
325 | 298 args.push_back(DtoBitCast(src,getVoidPtrType())); |
326 llvm::Value* ret = llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 299 args.push_back(DtoConstInt(global.params.is64bit ? 16 : 8)); |
327 | 300 args.push_back(DtoConstInt(0)); |
328 return ret; | 301 gIR->ir->CreateCall(GET_INTRINSIC_DECL(memcpy_i32), args.begin(), args.end(), ""); |
329 } | 302 } |
330 | 303 |
331 ////////////////////////////////////////////////////////////////////////////////////////// | 304 ////////////////////////////////////////////////////////////////////////////////////////// |
332 | 305 |
333 llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src) | 306 LLValue* DtoDelegateCompare(TOK op, LLValue* lhs, LLValue* rhs) |
334 { | |
335 assert(dst->getType() == src->getType()); | |
336 assert(gIR); | |
337 | |
338 d_uns64 n = (global.params.is64bit) ? 16 : 8; | |
339 | |
340 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); | |
341 | |
342 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | |
343 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); | |
344 | |
345 llvm::Function* fn = LLVM_DeclareMemCpy32(); | |
346 std::vector<llvm::Value*> llargs; | |
347 llargs.resize(4); | |
348 llargs[0] = dstarr; | |
349 llargs[1] = srcarr; | |
350 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
351 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
352 | |
353 return llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
354 } | |
355 | |
356 ////////////////////////////////////////////////////////////////////////////////////////// | |
357 | |
358 llvm::Value* DtoDelegateCompare(TOK op, llvm::Value* lhs, llvm::Value* rhs) | |
359 { | 307 { |
360 Logger::println("Doing delegate compare"); | 308 Logger::println("Doing delegate compare"); |
361 llvm::ICmpInst::Predicate pred = (op == TOKequal || op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; | 309 llvm::ICmpInst::Predicate pred = (op == TOKequal || op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; |
362 llvm::Value *b1, *b2; | 310 llvm::Value *b1, *b2; |
363 if (rhs == NULL) | 311 if (rhs == NULL) |
364 { | 312 { |
365 llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); | 313 LLValue* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); |
366 llvm::Value* r = llvm::Constant::getNullValue(l->getType()); | 314 LLValue* r = llvm::Constant::getNullValue(l->getType()); |
367 b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); | 315 b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); |
368 l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); | 316 l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); |
369 r = llvm::Constant::getNullValue(l->getType()); | 317 r = llvm::Constant::getNullValue(l->getType()); |
370 b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); | 318 b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); |
371 } | 319 } |
372 else | 320 else |
373 { | 321 { |
374 llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); | 322 LLValue* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); |
375 llvm::Value* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp"); | 323 LLValue* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp"); |
376 b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); | 324 b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); |
377 l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); | 325 l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); |
378 r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp"); | 326 r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp"); |
379 b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); | 327 b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); |
380 } | 328 } |
381 llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); | 329 LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp"); |
382 if (op == TOKnotequal || op == TOKnotidentity) | 330 if (op == TOKnotequal || op == TOKnotidentity) |
383 return gIR->ir->CreateNot(b,"tmp"); | 331 return gIR->ir->CreateNot(b,"tmp"); |
384 return b; | 332 return b; |
385 } | 333 } |
386 | 334 |
465 assert(0 && "Unsupported calling convention"); | 413 assert(0 && "Unsupported calling convention"); |
466 } | 414 } |
467 | 415 |
468 ////////////////////////////////////////////////////////////////////////////////////////// | 416 ////////////////////////////////////////////////////////////////////////////////////////// |
469 | 417 |
470 llvm::Value* DtoPointedType(llvm::Value* ptr, llvm::Value* val) | 418 LLValue* DtoPointedType(LLValue* ptr, LLValue* val) |
471 { | 419 { |
472 const llvm::Type* ptrTy = ptr->getType()->getContainedType(0); | 420 const LLType* ptrTy = ptr->getType()->getContainedType(0); |
473 const llvm::Type* valTy = val->getType(); | 421 const LLType* valTy = val->getType(); |
474 // ptr points to val's type | 422 // ptr points to val's type |
475 if (ptrTy == valTy) | 423 if (ptrTy == valTy) |
476 { | 424 { |
477 return val; | 425 return val; |
478 } | 426 } |
498 return 0; | 446 return 0; |
499 } | 447 } |
500 | 448 |
501 ////////////////////////////////////////////////////////////////////////////////////////// | 449 ////////////////////////////////////////////////////////////////////////////////////////// |
502 | 450 |
503 llvm::Value* DtoBoolean(llvm::Value* val) | 451 LLValue* DtoBoolean(LLValue* val) |
504 { | 452 { |
505 const llvm::Type* t = val->getType(); | 453 const LLType* t = val->getType(); |
506 if (t->isInteger()) | 454 if (t->isInteger()) |
507 { | 455 { |
508 if (t == llvm::Type::Int1Ty) | 456 if (t == llvm::Type::Int1Ty) |
509 return val; | 457 return val; |
510 else { | 458 else { |
511 llvm::Value* zero = llvm::ConstantInt::get(t, 0, false); | 459 LLValue* zero = llvm::ConstantInt::get(t, 0, false); |
512 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb()); | 460 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb()); |
513 } | 461 } |
514 } | 462 } |
515 else if (isaPointer(t)) { | 463 else if (isaPointer(t)) { |
516 llvm::Value* zero = llvm::Constant::getNullValue(t); | 464 LLValue* zero = llvm::Constant::getNullValue(t); |
517 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb()); | 465 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb()); |
518 } | 466 } |
519 else | 467 else |
520 { | 468 { |
521 Logger::cout() << *t << '\n'; | 469 Logger::cout() << *t << '\n'; |
524 return 0; | 472 return 0; |
525 } | 473 } |
526 | 474 |
527 ////////////////////////////////////////////////////////////////////////////////////////// | 475 ////////////////////////////////////////////////////////////////////////////////////////// |
528 | 476 |
529 const llvm::Type* DtoSize_t() | 477 const LLType* DtoSize_t() |
530 { | 478 { |
531 if (global.params.is64bit) | 479 if (global.params.is64bit) |
532 return llvm::Type::Int64Ty; | 480 return llvm::Type::Int64Ty; |
533 else | 481 else |
534 return llvm::Type::Int32Ty; | 482 return llvm::Type::Int32Ty; |
535 } | 483 } |
536 | 484 |
537 ////////////////////////////////////////////////////////////////////////////////////////// | 485 ////////////////////////////////////////////////////////////////////////////////////////// |
538 | 486 |
539 llvm::Constant* DtoConstInitializer(Type* type, Initializer* init) | 487 LLConstant* DtoConstInitializer(Type* type, Initializer* init) |
540 { | 488 { |
541 llvm::Constant* _init = 0; // may return zero | 489 LLConstant* _init = 0; // may return zero |
542 if (!init) | 490 if (!init) |
543 { | 491 { |
544 Logger::println("const default initializer for %s", type->toChars()); | 492 Logger::println("const default initializer for %s", type->toChars()); |
545 _init = type->defaultInit()->toConstElem(gIR); | 493 _init = type->defaultInit()->toConstElem(gIR); |
546 } | 494 } |
560 _init = DtoConstArrayInitializer(ai); | 508 _init = DtoConstArrayInitializer(ai); |
561 } | 509 } |
562 else if (init->isVoidInitializer()) | 510 else if (init->isVoidInitializer()) |
563 { | 511 { |
564 Logger::println("const void initializer"); | 512 Logger::println("const void initializer"); |
565 const llvm::Type* ty = DtoType(type); | 513 const LLType* ty = DtoType(type); |
566 _init = llvm::Constant::getNullValue(ty); | 514 _init = llvm::Constant::getNullValue(ty); |
567 } | 515 } |
568 else { | 516 else { |
569 Logger::println("unsupported const initializer: %s", init->toChars()); | 517 Logger::println("unsupported const initializer: %s", init->toChars()); |
570 } | 518 } |
571 return _init; | 519 return _init; |
572 } | 520 } |
573 | 521 |
574 ////////////////////////////////////////////////////////////////////////////////////////// | 522 ////////////////////////////////////////////////////////////////////////////////////////// |
575 | 523 |
576 llvm::Constant* DtoConstFieldInitializer(Type* t, Initializer* init) | 524 LLConstant* DtoConstFieldInitializer(Type* t, Initializer* init) |
577 { | 525 { |
578 Logger::println("DtoConstFieldInitializer"); | 526 Logger::println("DtoConstFieldInitializer"); |
579 LOG_SCOPE; | 527 LOG_SCOPE; |
580 | 528 |
581 const llvm::Type* _type = DtoType(t); | 529 const LLType* _type = DtoType(t); |
582 | 530 |
583 llvm::Constant* _init = DtoConstInitializer(t, init); | 531 LLConstant* _init = DtoConstInitializer(t, init); |
584 assert(_init); | 532 assert(_init); |
585 if (_type != _init->getType()) | 533 if (_type != _init->getType()) |
586 { | 534 { |
587 Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n'; | 535 Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n'; |
588 if (t->ty == Tsarray) | 536 if (t->ty == Tsarray) |
589 { | 537 { |
590 const llvm::ArrayType* arrty = isaArray(_type); | 538 const llvm::ArrayType* arrty = isaArray(_type); |
591 uint64_t n = arrty->getNumElements(); | 539 uint64_t n = arrty->getNumElements(); |
592 std::vector<llvm::Constant*> vals(n,_init); | 540 std::vector<LLConstant*> vals(n,_init); |
593 _init = llvm::ConstantArray::get(arrty, vals); | 541 _init = llvm::ConstantArray::get(arrty, vals); |
594 } | 542 } |
595 else if (t->ty == Tarray) | 543 else if (t->ty == Tarray) |
596 { | 544 { |
597 assert(isaStruct(_type)); | 545 assert(isaStruct(_type)); |
640 return 0; | 588 return 0; |
641 } | 589 } |
642 | 590 |
643 ////////////////////////////////////////////////////////////////////////////////////////// | 591 ////////////////////////////////////////////////////////////////////////////////////////// |
644 | 592 |
645 llvm::Value* DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb) | 593 LLValue* DtoGEP(LLValue* ptr, LLValue* i0, LLValue* i1, const std::string& var, llvm::BasicBlock* bb) |
646 { | 594 { |
647 std::vector<llvm::Value*> v(2); | 595 std::vector<LLValue*> v(2); |
648 v[0] = i0; | 596 v[0] = i0; |
649 v[1] = i1; | 597 v[1] = i1; |
650 Logger::cout() << "DtoGEP: " << *ptr << ", " << *i0 << ", " << *i1 << '\n'; | 598 Logger::cout() << "DtoGEP: " << *ptr << ", " << *i0 << ", " << *i1 << '\n'; |
651 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); | 599 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
652 } | 600 } |
653 | 601 |
654 ////////////////////////////////////////////////////////////////////////////////////////// | 602 ////////////////////////////////////////////////////////////////////////////////////////// |
655 | 603 |
656 llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) | 604 LLValue* DtoGEP(LLValue* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) |
657 { | 605 { |
658 size_t n = src.size(); | 606 size_t n = src.size(); |
659 std::vector<llvm::Value*> dst(n, NULL); | 607 std::vector<LLValue*> dst(n, NULL); |
660 //std::ostream& ostr = Logger::cout(); | 608 //std::ostream& ostr = Logger::cout(); |
661 //ostr << "indices for '" << *ptr << "':"; | 609 //ostr << "indices for '" << *ptr << "':"; |
662 for (size_t i=0; i<n; ++i) | 610 for (size_t i=0; i<n; ++i) |
663 { | 611 { |
664 //ostr << ' ' << i; | 612 //ostr << ' ' << i; |
668 return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); | 616 return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); |
669 } | 617 } |
670 | 618 |
671 ////////////////////////////////////////////////////////////////////////////////////////// | 619 ////////////////////////////////////////////////////////////////////////////////////////// |
672 | 620 |
673 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb) | 621 LLValue* DtoGEPi(LLValue* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb) |
674 { | 622 { |
675 return llvm::GetElementPtrInst::Create(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); | 623 return llvm::GetElementPtrInst::Create(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); |
676 } | 624 } |
677 | 625 |
678 ////////////////////////////////////////////////////////////////////////////////////////// | 626 ////////////////////////////////////////////////////////////////////////////////////////// |
679 | 627 |
680 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb) | 628 LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb) |
681 { | 629 { |
682 std::vector<llvm::Value*> v(2); | 630 std::vector<LLValue*> v(2); |
683 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); | 631 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); |
684 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); | 632 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); |
685 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); | 633 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
686 } | 634 } |
687 | 635 |
688 ////////////////////////////////////////////////////////////////////////////////////////// | 636 ////////////////////////////////////////////////////////////////////////////////////////// |
689 | 637 |
690 llvm::Value* DtoNew(Type* newtype) | 638 LLValue* DtoNew(Type* newtype) |
691 { | 639 { |
692 // get runtime function | 640 // get runtime function |
693 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT"); | 641 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT"); |
694 // get type info | 642 // get type info |
695 llvm::Constant* ti = DtoTypeInfoOf(newtype); | 643 LLConstant* ti = DtoTypeInfoOf(newtype); |
696 assert(isaPointer(ti)); | 644 assert(isaPointer(ti)); |
697 // call runtime | 645 // call runtime |
698 llvm::SmallVector<llvm::Value*,1> arg; | 646 LLSmallVector<LLValue*,1> arg; |
699 arg.push_back(ti); | 647 arg.push_back(ti); |
700 // allocate | 648 // allocate |
701 llvm::Value* mem = gIR->ir->CreateCall(fn, arg.begin(), arg.end(), ".gc_mem"); | 649 LLValue* mem = gIR->ir->CreateCall(fn, arg.begin(), arg.end(), ".gc_mem"); |
702 // cast | 650 // cast |
703 return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem"); | 651 return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem"); |
704 } | 652 } |
705 | 653 |
706 void DtoDeleteMemory(llvm::Value* ptr) | 654 void DtoDeleteMemory(LLValue* ptr) |
707 { | 655 { |
708 // get runtime function | 656 // get runtime function |
709 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delmemory"); | 657 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delmemory"); |
710 // build args | 658 // build args |
711 llvm::SmallVector<llvm::Value*,1> arg; | 659 LLSmallVector<LLValue*,1> arg; |
712 arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp")); | 660 arg.push_back(DtoBitCast(ptr, getVoidPtrType(), ".tmp")); |
713 // call | 661 // call |
714 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); | 662 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); |
715 } | 663 } |
716 | 664 |
717 void DtoDeleteClass(llvm::Value* inst) | 665 void DtoDeleteClass(LLValue* inst) |
718 { | 666 { |
719 // get runtime function | 667 // get runtime function |
720 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delclass"); | 668 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delclass"); |
721 // build args | 669 // build args |
722 llvm::SmallVector<llvm::Value*,1> arg; | 670 LLSmallVector<LLValue*,1> arg; |
723 arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); | 671 arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); |
724 // call | 672 // call |
725 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); | 673 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); |
726 } | 674 } |
727 | 675 |
728 void DtoDeleteInterface(llvm::Value* inst) | 676 void DtoDeleteInterface(LLValue* inst) |
729 { | 677 { |
730 // get runtime function | 678 // get runtime function |
731 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delinterface"); | 679 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delinterface"); |
732 // build args | 680 // build args |
733 llvm::SmallVector<llvm::Value*,1> arg; | 681 LLSmallVector<LLValue*,1> arg; |
734 arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); | 682 arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); |
735 // call | 683 // call |
736 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); | 684 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); |
737 } | 685 } |
738 | 686 |
739 void DtoDeleteArray(DValue* arr) | 687 void DtoDeleteArray(DValue* arr) |
740 { | 688 { |
741 // get runtime function | 689 // get runtime function |
742 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delarray"); | 690 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_delarray"); |
743 // build args | 691 // build args |
744 llvm::SmallVector<llvm::Value*,2> arg; | 692 LLSmallVector<LLValue*,2> arg; |
745 arg.push_back(DtoArrayLen(arr)); | 693 arg.push_back(DtoArrayLen(arr)); |
746 arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp")); | 694 arg.push_back(DtoBitCast(DtoArrayPtr(arr), getVoidPtrType(), ".tmp")); |
747 // call | 695 // call |
748 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); | 696 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); |
749 } | 697 } |
750 | 698 |
751 ////////////////////////////////////////////////////////////////////////////////////////// | 699 ////////////////////////////////////////////////////////////////////////////////////////// |
752 | 700 |
753 void DtoAssert(Loc* loc, DValue* msg) | 701 void DtoAssert(Loc* loc, DValue* msg) |
754 { | 702 { |
755 std::vector<llvm::Value*> args; | 703 std::vector<LLValue*> args; |
756 llvm::Constant* c; | 704 LLConstant* c; |
757 | 705 |
758 // func | 706 // func |
759 const char* fname = msg ? "_d_assert_msg" : "_d_assert"; | 707 const char* fname = msg ? "_d_assert_msg" : "_d_assert"; |
760 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); | 708 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); |
761 | 709 |
786 if (!alloc) | 734 if (!alloc) |
787 { | 735 { |
788 alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint()); | 736 alloc = new llvm::AllocaInst(c->getType(), ".srcfile", gIR->topallocapoint()); |
789 gIR->func()->srcfileArg = alloc; | 737 gIR->func()->srcfileArg = alloc; |
790 } | 738 } |
791 llvm::Value* ptr = DtoGEPi(alloc, 0,0, "tmp"); | 739 LLValue* ptr = DtoGEPi(alloc, 0,0, "tmp"); |
792 DtoStore(c->getOperand(0), ptr); | 740 DtoStore(c->getOperand(0), ptr); |
793 ptr = DtoGEPi(alloc, 0,1, "tmp"); | 741 ptr = DtoGEPi(alloc, 0,1, "tmp"); |
794 DtoStore(c->getOperand(1), ptr); | 742 DtoStore(c->getOperand(1), ptr); |
795 args.push_back(alloc); | 743 args.push_back(alloc); |
796 | 744 |
802 llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); | 750 llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); |
803 } | 751 } |
804 | 752 |
805 ////////////////////////////////////////////////////////////////////////////////////////// | 753 ////////////////////////////////////////////////////////////////////////////////////////// |
806 | 754 |
807 static const llvm::Type* get_next_frame_ptr_type(Dsymbol* sc) | 755 static const LLType* get_next_frame_ptr_type(Dsymbol* sc) |
808 { | 756 { |
809 assert(sc->isFuncDeclaration() || sc->isClassDeclaration()); | 757 assert(sc->isFuncDeclaration() || sc->isClassDeclaration()); |
810 Dsymbol* p = sc->toParent2(); | 758 Dsymbol* p = sc->toParent2(); |
811 if (!p->isFuncDeclaration() && !p->isClassDeclaration()) | 759 if (!p->isFuncDeclaration() && !p->isClassDeclaration()) |
812 Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind()); | 760 Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind()); |
813 assert(p->isFuncDeclaration() || p->isClassDeclaration()); | 761 assert(p->isFuncDeclaration() || p->isClassDeclaration()); |
814 if (FuncDeclaration* fd = p->isFuncDeclaration()) | 762 if (FuncDeclaration* fd = p->isFuncDeclaration()) |
815 { | 763 { |
816 llvm::Value* v = fd->ir.irFunc->nestedVar; | 764 LLValue* v = fd->ir.irFunc->nestedVar; |
817 assert(v); | 765 assert(v); |
818 return v->getType(); | 766 return v->getType(); |
819 } | 767 } |
820 else if (ClassDeclaration* cd = p->isClassDeclaration()) | 768 else if (ClassDeclaration* cd = p->isClassDeclaration()) |
821 { | 769 { |
828 } | 776 } |
829 } | 777 } |
830 | 778 |
831 ////////////////////////////////////////////////////////////////////////////////////////// | 779 ////////////////////////////////////////////////////////////////////////////////////////// |
832 | 780 |
833 static llvm::Value* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, llvm::Value* v) | 781 static LLValue* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, LLValue* v) |
834 { | 782 { |
835 LOG_SCOPE; | 783 LOG_SCOPE; |
836 if (sc == func) | 784 if (sc == func) |
837 { | 785 { |
838 return v; | 786 return v; |
886 } | 834 } |
887 } | 835 } |
888 | 836 |
889 ////////////////////////////////////////////////////////////////////////////////////////// | 837 ////////////////////////////////////////////////////////////////////////////////////////// |
890 | 838 |
891 static llvm::Value* get_frame_ptr(FuncDeclaration* func) | 839 static LLValue* get_frame_ptr(FuncDeclaration* func) |
892 { | 840 { |
893 Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars()); | 841 Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars()); |
894 LOG_SCOPE; | 842 LOG_SCOPE; |
895 IrFunction* irfunc = gIR->func(); | 843 IrFunction* irfunc = gIR->func(); |
896 | 844 |
897 // in the right scope already | 845 // in the right scope already |
898 if (func == irfunc->decl) | 846 if (func == irfunc->decl) |
899 return irfunc->decl->ir.irFunc->nestedVar; | 847 return irfunc->decl->ir.irFunc->nestedVar; |
900 | 848 |
901 // use the 'this' pointer | 849 // use the 'this' pointer |
902 llvm::Value* ptr = irfunc->decl->ir.irFunc->thisVar; | 850 LLValue* ptr = irfunc->decl->ir.irFunc->thisVar; |
903 assert(ptr); | 851 assert(ptr); |
904 | 852 |
905 // return the fully resolved frame pointer | 853 // return the fully resolved frame pointer |
906 ptr = get_frame_ptr_impl(func, irfunc->decl, ptr); | 854 ptr = get_frame_ptr_impl(func, irfunc->decl, ptr); |
907 if (ptr) Logger::cout() << "Found context!" << *ptr; | 855 if (ptr) Logger::cout() << "Found context!" << *ptr; |
910 return ptr; | 858 return ptr; |
911 } | 859 } |
912 | 860 |
913 ////////////////////////////////////////////////////////////////////////////////////////// | 861 ////////////////////////////////////////////////////////////////////////////////////////// |
914 | 862 |
915 llvm::Value* DtoNestedContext(FuncDeclaration* func) | 863 LLValue* DtoNestedContext(FuncDeclaration* func) |
916 { | 864 { |
917 // resolve frame ptr | 865 // resolve frame ptr |
918 llvm::Value* ptr = get_frame_ptr(func); | 866 LLValue* ptr = get_frame_ptr(func); |
919 Logger::cout() << "Nested context ptr = "; | 867 Logger::cout() << "Nested context ptr = "; |
920 if (ptr) Logger::cout() << *ptr; | 868 if (ptr) Logger::cout() << *ptr; |
921 else Logger::cout() << "NULL"; | 869 else Logger::cout() << "NULL"; |
922 Logger::cout() << '\n'; | 870 Logger::cout() << '\n'; |
923 return ptr; | 871 return ptr; |
951 Logger::println("Done"); | 899 Logger::println("Done"); |
952 } | 900 } |
953 | 901 |
954 ////////////////////////////////////////////////////////////////////////////////////////// | 902 ////////////////////////////////////////////////////////////////////////////////////////// |
955 | 903 |
956 llvm::Value* DtoNestedVariable(VarDeclaration* vd) | 904 LLValue* DtoNestedVariable(VarDeclaration* vd) |
957 { | 905 { |
958 // log the frame list | 906 // log the frame list |
959 IrFunction* irfunc = gIR->func(); | 907 IrFunction* irfunc = gIR->func(); |
960 if (Logger::enabled()) | 908 if (Logger::enabled()) |
961 print_nested_frame_list(vd, irfunc->decl); | 909 print_nested_frame_list(vd, irfunc->decl); |
962 | 910 |
963 // resolve frame ptr | 911 // resolve frame ptr |
964 FuncDeclaration* func = vd->toParent2()->isFuncDeclaration(); | 912 FuncDeclaration* func = vd->toParent2()->isFuncDeclaration(); |
965 assert(func); | 913 assert(func); |
966 llvm::Value* ptr = DtoNestedContext(func); | 914 LLValue* ptr = DtoNestedContext(func); |
967 assert(ptr && "nested var, but no context"); | 915 assert(ptr && "nested var, but no context"); |
968 | 916 |
969 // we must cast here to be sure. nested classes just have a void* | 917 // we must cast here to be sure. nested classes just have a void* |
970 ptr = DtoBitCast(ptr, func->ir.irFunc->nestedVar->getType()); | 918 ptr = DtoBitCast(ptr, func->ir.irFunc->nestedVar->getType()); |
971 | 919 |
972 // index nested var and load (if necessary) | 920 // index nested var and load (if necessary) |
973 llvm::Value* v = DtoGEPi(ptr, 0, vd->ir.irLocal->nestedIndex, "tmp"); | 921 LLValue* v = DtoGEPi(ptr, 0, vd->ir.irLocal->nestedIndex, "tmp"); |
974 // references must be loaded, for normal variables this IS already the variable storage!!! | 922 // references must be loaded, for normal variables this IS already the variable storage!!! |
975 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) | 923 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) |
976 v = DtoLoad(v); | 924 v = DtoLoad(v); |
977 | 925 |
978 // log and return | 926 // log and return |
1016 } | 964 } |
1017 } | 965 } |
1018 // rhs is slice | 966 // rhs is slice |
1019 else if (DSliceValue* s = rhs->isSlice()) { | 967 else if (DSliceValue* s = rhs->isSlice()) { |
1020 assert(s->getType()->toBasetype() == lhs->getType()->toBasetype()); | 968 assert(s->getType()->toBasetype() == lhs->getType()->toBasetype()); |
1021 DtoSetArray(lhs->getLVal(),s->len,s->ptr); | 969 DtoSetArray(lhs->getLVal(),DtoArrayLen(s),DtoArrayPtr(s)); |
1022 } | 970 } |
1023 // null | 971 // null |
1024 else if (rhs->isNull()) { | 972 else if (rhs->isNull()) { |
1025 DtoSetArrayToNull(lhs->getLVal()); | 973 DtoSetArrayToNull(lhs->getLVal()); |
1026 } | 974 } |
1039 } | 987 } |
1040 else if (t->ty == Tdelegate) { | 988 else if (t->ty == Tdelegate) { |
1041 if (rhs->isNull()) | 989 if (rhs->isNull()) |
1042 DtoDelegateToNull(lhs->getLVal()); | 990 DtoDelegateToNull(lhs->getLVal()); |
1043 else if (!rhs->inPlace()) { | 991 else if (!rhs->inPlace()) { |
1044 llvm::Value* l = lhs->getLVal(); | 992 LLValue* l = lhs->getLVal(); |
1045 llvm::Value* r = rhs->getRVal(); | 993 LLValue* r = rhs->getRVal(); |
1046 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; | 994 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; |
1047 DtoDelegateCopy(l, r); | 995 DtoDelegateCopy(l, r); |
1048 } | 996 } |
1049 } | 997 } |
1050 else if (t->ty == Tclass) { | 998 else if (t->ty == Tclass) { |
1051 assert(t2->ty == Tclass); | 999 assert(t2->ty == Tclass); |
1052 // assignment to this in constructor special case | 1000 // assignment to this in constructor special case |
1053 if (lhs->isThis()) { | 1001 if (lhs->isThis()) { |
1054 llvm::Value* tmp = rhs->getRVal(); | 1002 LLValue* tmp = rhs->getRVal(); |
1055 FuncDeclaration* fdecl = gIR->func()->decl; | 1003 FuncDeclaration* fdecl = gIR->func()->decl; |
1056 // respecify the this param | 1004 // respecify the this param |
1057 if (!llvm::isa<llvm::AllocaInst>(fdecl->ir.irFunc->thisVar)) | 1005 if (!llvm::isa<llvm::AllocaInst>(fdecl->ir.irFunc->thisVar)) |
1058 fdecl->ir.irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); | 1006 fdecl->ir.irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); |
1059 DtoStore(tmp, fdecl->ir.irFunc->thisVar); | 1007 DtoStore(tmp, fdecl->ir.irFunc->thisVar); |
1064 } | 1012 } |
1065 } | 1013 } |
1066 else if (t->iscomplex()) { | 1014 else if (t->iscomplex()) { |
1067 assert(!lhs->isComplex()); | 1015 assert(!lhs->isComplex()); |
1068 | 1016 |
1069 llvm::Value* dst; | 1017 LLValue* dst; |
1070 if (DLRValue* lr = lhs->isLRValue()) { | 1018 if (DLRValue* lr = lhs->isLRValue()) { |
1071 dst = lr->getLVal(); | 1019 dst = lr->getLVal(); |
1072 rhs = DtoCastComplex(rhs, lr->getLType()); | 1020 rhs = DtoCastComplex(rhs, lr->getLType()); |
1073 } | 1021 } |
1074 else { | 1022 else { |
1079 DtoComplexSet(dst, cx->re, cx->im); | 1027 DtoComplexSet(dst, cx->re, cx->im); |
1080 else | 1028 else |
1081 DtoComplexAssign(dst, rhs->getRVal()); | 1029 DtoComplexAssign(dst, rhs->getRVal()); |
1082 } | 1030 } |
1083 else { | 1031 else { |
1084 llvm::Value* l = lhs->getLVal(); | 1032 LLValue* l = lhs->getLVal(); |
1085 llvm::Value* r = rhs->getRVal(); | 1033 LLValue* r = rhs->getRVal(); |
1086 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; | 1034 Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; |
1087 const llvm::Type* lit = l->getType()->getContainedType(0); | 1035 const LLType* lit = l->getType()->getContainedType(0); |
1088 if (r->getType() != lit) { | 1036 if (r->getType() != lit) { |
1089 // handle lvalue cast assignments | 1037 // handle lvalue cast assignments |
1090 if (DLRValue* lr = lhs->isLRValue()) { | 1038 if (DLRValue* lr = lhs->isLRValue()) { |
1091 Logger::println("lvalue cast!"); | 1039 Logger::println("lvalue cast!"); |
1092 r = DtoCast(rhs, lr->getLType())->getRVal(); | 1040 r = DtoCast(rhs, lr->getLType())->getRVal(); |
1102 } | 1050 } |
1103 | 1051 |
1104 ////////////////////////////////////////////////////////////////////////////////////////// | 1052 ////////////////////////////////////////////////////////////////////////////////////////// |
1105 DValue* DtoCastInt(DValue* val, Type* _to) | 1053 DValue* DtoCastInt(DValue* val, Type* _to) |
1106 { | 1054 { |
1107 const llvm::Type* tolltype = DtoType(_to); | 1055 const LLType* tolltype = DtoType(_to); |
1108 | 1056 |
1109 Type* to = DtoDType(_to); | 1057 Type* to = DtoDType(_to); |
1110 Type* from = DtoDType(val->getType()); | 1058 Type* from = DtoDType(val->getType()); |
1111 assert(from->isintegral()); | 1059 assert(from->isintegral()); |
1112 | 1060 |
1113 size_t fromsz = from->size(); | 1061 size_t fromsz = from->size(); |
1114 size_t tosz = to->size(); | 1062 size_t tosz = to->size(); |
1115 | 1063 |
1116 llvm::Value* rval = val->getRVal(); | 1064 LLValue* rval = val->getRVal(); |
1117 if (rval->getType() == tolltype) { | 1065 if (rval->getType() == tolltype) { |
1118 return new DImValue(_to, rval); | 1066 return new DImValue(_to, rval); |
1119 } | 1067 } |
1120 | 1068 |
1121 if (to->isintegral()) { | 1069 if (to->isintegral()) { |
1129 } | 1077 } |
1130 else if (fromsz > tosz) { | 1078 else if (fromsz > tosz) { |
1131 rval = new llvm::TruncInst(rval, tolltype, "tmp", gIR->scopebb()); | 1079 rval = new llvm::TruncInst(rval, tolltype, "tmp", gIR->scopebb()); |
1132 } | 1080 } |
1133 else { | 1081 else { |
1134 rval = new llvm::BitCastInst(rval, tolltype, "tmp", gIR->scopebb()); | 1082 rval = DtoBitCast(rval, tolltype); |
1135 } | 1083 } |
1136 } | 1084 } |
1137 else if (to->isfloating()) { | 1085 else if (to->isfloating()) { |
1138 if (from->isunsigned()) { | 1086 if (from->isunsigned()) { |
1139 rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); | 1087 rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); |
1153 return new DImValue(_to, rval); | 1101 return new DImValue(_to, rval); |
1154 } | 1102 } |
1155 | 1103 |
1156 DValue* DtoCastPtr(DValue* val, Type* to) | 1104 DValue* DtoCastPtr(DValue* val, Type* to) |
1157 { | 1105 { |
1158 const llvm::Type* tolltype = DtoType(to); | 1106 const LLType* tolltype = DtoType(to); |
1159 | 1107 |
1160 Type* totype = DtoDType(to); | 1108 Type* totype = DtoDType(to); |
1161 Type* fromtype = DtoDType(val->getType()); | 1109 Type* fromtype = DtoDType(val->getType()); |
1162 assert(fromtype->ty == Tpointer); | 1110 assert(fromtype->ty == Tpointer); |
1163 | 1111 |
1164 llvm::Value* rval; | 1112 LLValue* rval; |
1165 | 1113 |
1166 if (totype->ty == Tpointer || totype->ty == Tclass) { | 1114 if (totype->ty == Tpointer || totype->ty == Tclass) { |
1167 llvm::Value* src = val->getRVal(); | 1115 LLValue* src = val->getRVal(); |
1168 Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n'; | 1116 Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n'; |
1169 rval = new llvm::BitCastInst(src, tolltype, "tmp", gIR->scopebb()); | 1117 rval = DtoBitCast(src, tolltype); |
1170 } | 1118 } |
1171 else if (totype->isintegral()) { | 1119 else if (totype->isintegral()) { |
1172 rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); | 1120 rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); |
1173 } | 1121 } |
1174 else { | 1122 else { |
1182 DValue* DtoCastFloat(DValue* val, Type* to) | 1130 DValue* DtoCastFloat(DValue* val, Type* to) |
1183 { | 1131 { |
1184 if (val->getType() == to) | 1132 if (val->getType() == to) |
1185 return val; | 1133 return val; |
1186 | 1134 |
1187 const llvm::Type* tolltype = DtoType(to); | 1135 const LLType* tolltype = DtoType(to); |
1188 | 1136 |
1189 Type* totype = DtoDType(to); | 1137 Type* totype = DtoDType(to); |
1190 Type* fromtype = DtoDType(val->getType()); | 1138 Type* fromtype = DtoDType(val->getType()); |
1191 assert(fromtype->isfloating()); | 1139 assert(fromtype->isfloating()); |
1192 | 1140 |
1193 size_t fromsz = fromtype->size(); | 1141 size_t fromsz = fromtype->size(); |
1194 size_t tosz = totype->size(); | 1142 size_t tosz = totype->size(); |
1195 | 1143 |
1196 llvm::Value* rval; | 1144 LLValue* rval; |
1197 | 1145 |
1198 if (totype->iscomplex()) { | 1146 if (totype->iscomplex()) { |
1199 assert(0); | 1147 assert(0); |
1200 //return new DImValue(to, DtoComplex(to, val)); | 1148 //return new DImValue(to, DtoComplex(to, val)); |
1201 } | 1149 } |
1236 if (vty->size() == to->size()) | 1184 if (vty->size() == to->size()) |
1237 return val; | 1185 return val; |
1238 | 1186 |
1239 llvm::Value *re, *im; | 1187 llvm::Value *re, *im; |
1240 DtoGetComplexParts(val, re, im); | 1188 DtoGetComplexParts(val, re, im); |
1241 const llvm::Type* toty = DtoComplexBaseType(to); | 1189 const LLType* toty = DtoComplexBaseType(to); |
1242 | 1190 |
1243 if (to->size() < vty->size()) { | 1191 if (to->size() < vty->size()) { |
1244 re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); | 1192 re = gIR->ir->CreateFPTrunc(re, toty, "tmp"); |
1245 im = gIR->ir->CreateFPTrunc(im, toty, "tmp"); | 1193 im = gIR->ir->CreateFPTrunc(im, toty, "tmp"); |
1246 } | 1194 } |
1255 if (val->isComplex()) | 1203 if (val->isComplex()) |
1256 return new DComplexValue(_to, re, im); | 1204 return new DComplexValue(_to, re, im); |
1257 | 1205 |
1258 // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. | 1206 // unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions. |
1259 // so we need to give it storage, or fix the system that handles this stuff (DLRValue) | 1207 // so we need to give it storage, or fix the system that handles this stuff (DLRValue) |
1260 llvm::Value* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint()); | 1208 LLValue* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint()); |
1261 DtoComplexSet(mem, re, im); | 1209 DtoComplexSet(mem, re, im); |
1262 return new DLRValue(val->getType(), val->getRVal(), _to, mem); | 1210 return new DLRValue(val->getType(), val->getRVal(), _to, mem); |
1263 } | 1211 } |
1264 else if (to->isimaginary()) { | 1212 else if (to->isimaginary()) { |
1265 if (val->isComplex()) | 1213 if (val->isComplex()) |
1266 return new DImValue(to, val->isComplex()->im); | 1214 return new DImValue(to, val->isComplex()->im); |
1267 llvm::Value* v = val->getRVal(); | 1215 LLValue* v = val->getRVal(); |
1268 DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp"))); | 1216 DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp"))); |
1269 return DtoCastFloat(im, to); | 1217 return DtoCastFloat(im, to); |
1270 } | 1218 } |
1271 else if (to->isfloating()) { | 1219 else if (to->isfloating()) { |
1272 if (val->isComplex()) | 1220 if (val->isComplex()) |
1273 return new DImValue(to, val->isComplex()->re); | 1221 return new DImValue(to, val->isComplex()->re); |
1274 llvm::Value* v = val->getRVal(); | 1222 LLValue* v = val->getRVal(); |
1275 DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp"))); | 1223 DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp"))); |
1276 return DtoCastFloat(re, to); | 1224 return DtoCastFloat(re, to); |
1277 } | 1225 } |
1278 else | 1226 else |
1279 assert(0); | 1227 assert(0); |
1318 } | 1266 } |
1319 llvm::ConstantInt* DtoConstInt(int i) | 1267 llvm::ConstantInt* DtoConstInt(int i) |
1320 { | 1268 { |
1321 return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, true); | 1269 return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, true); |
1322 } | 1270 } |
1323 llvm::Constant* DtoConstBool(bool b) | 1271 LLConstant* DtoConstBool(bool b) |
1324 { | 1272 { |
1325 return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false); | 1273 return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false); |
1326 } | 1274 } |
1327 | 1275 |
1328 llvm::ConstantFP* DtoConstFP(Type* t, long double value) | 1276 llvm::ConstantFP* DtoConstFP(Type* t, long double value) |
1335 } | 1283 } |
1336 | 1284 |
1337 | 1285 |
1338 ////////////////////////////////////////////////////////////////////////////////////////// | 1286 ////////////////////////////////////////////////////////////////////////////////////////// |
1339 | 1287 |
1340 llvm::Constant* DtoConstString(const char* str) | 1288 LLConstant* DtoConstString(const char* str) |
1341 { | 1289 { |
1342 std::string s(str); | 1290 std::string s(str); |
1343 llvm::Constant* init = llvm::ConstantArray::get(s, true); | 1291 LLConstant* init = llvm::ConstantArray::get(s, true); |
1344 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( | 1292 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( |
1345 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); | 1293 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); |
1346 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; | 1294 LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; |
1347 return DtoConstSlice( | 1295 return DtoConstSlice( |
1348 DtoConstSize_t(s.length()), | 1296 DtoConstSize_t(s.length()), |
1349 llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2) | 1297 llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2) |
1350 ); | 1298 ); |
1351 } | 1299 } |
1352 llvm::Constant* DtoConstStringPtr(const char* str, const char* section) | 1300 LLConstant* DtoConstStringPtr(const char* str, const char* section) |
1353 { | 1301 { |
1354 std::string s(str); | 1302 std::string s(str); |
1355 llvm::Constant* init = llvm::ConstantArray::get(s, true); | 1303 LLConstant* init = llvm::ConstantArray::get(s, true); |
1356 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( | 1304 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( |
1357 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); | 1305 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); |
1358 if (section) gvar->setSection(section); | 1306 if (section) gvar->setSection(section); |
1359 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; | 1307 LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; |
1360 return llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | 1308 return llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
1361 } | 1309 } |
1362 | 1310 |
1363 ////////////////////////////////////////////////////////////////////////////////////////// | 1311 ////////////////////////////////////////////////////////////////////////////////////////// |
1364 | 1312 |
1365 void DtoMemSetZero(llvm::Value* dst, llvm::Value* nbytes) | 1313 void DtoMemSetZero(LLValue* dst, LLValue* nbytes) |
1366 { | 1314 { |
1367 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); | 1315 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); |
1368 llvm::Value *dstarr; | 1316 llvm::Value *dstarr; |
1369 if (dst->getType() == arrty) | 1317 if (dst->getType() == arrty) |
1370 { | 1318 { |
1371 dstarr = dst; | 1319 dstarr = dst; |
1372 } | 1320 } |
1373 else | 1321 else |
1374 { | 1322 { |
1375 dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | 1323 dstarr = DtoBitCast(dst,arrty); |
1376 } | 1324 } |
1377 | 1325 |
1378 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemSet64() : LLVM_DeclareMemSet32(); | 1326 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemSet64() : LLVM_DeclareMemSet32(); |
1379 std::vector<llvm::Value*> llargs; | 1327 std::vector<LLValue*> llargs; |
1380 llargs.resize(4); | 1328 llargs.resize(4); |
1381 llargs[0] = dstarr; | 1329 llargs[0] = dstarr; |
1382 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | 1330 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); |
1383 llargs[2] = nbytes; | 1331 llargs[2] = nbytes; |
1384 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1332 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1386 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 1334 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
1387 } | 1335 } |
1388 | 1336 |
1389 ////////////////////////////////////////////////////////////////////////////////////////// | 1337 ////////////////////////////////////////////////////////////////////////////////////////// |
1390 | 1338 |
1391 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes) | 1339 void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes) |
1392 { | 1340 { |
1393 const llvm::Type* arrty = getVoidPtrType(); | 1341 const LLType* arrty = getVoidPtrType(); |
1394 | 1342 |
1395 llvm::Value* dstarr; | 1343 LLValue* dstarr; |
1396 if (dst->getType() == arrty) | 1344 if (dst->getType() == arrty) |
1397 dstarr = dst; | 1345 dstarr = dst; |
1398 else | 1346 else |
1399 dstarr = DtoBitCast(dst, arrty, "tmp"); | 1347 dstarr = DtoBitCast(dst, arrty, "tmp"); |
1400 | 1348 |
1401 llvm::Value* srcarr; | 1349 LLValue* srcarr; |
1402 if (src->getType() == arrty) | 1350 if (src->getType() == arrty) |
1403 srcarr = src; | 1351 srcarr = src; |
1404 else | 1352 else |
1405 srcarr = DtoBitCast(src, arrty, "tmp"); | 1353 srcarr = DtoBitCast(src, arrty, "tmp"); |
1406 | 1354 |
1407 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); | 1355 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
1408 std::vector<llvm::Value*> llargs; | 1356 std::vector<LLValue*> llargs; |
1409 llargs.resize(4); | 1357 llargs.resize(4); |
1410 llargs[0] = dstarr; | 1358 llargs[0] = dstarr; |
1411 llargs[1] = srcarr; | 1359 llargs[1] = srcarr; |
1412 llargs[2] = nbytes; | 1360 llargs[2] = nbytes; |
1413 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1361 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1415 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 1363 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
1416 } | 1364 } |
1417 | 1365 |
1418 ////////////////////////////////////////////////////////////////////////////////////////// | 1366 ////////////////////////////////////////////////////////////////////////////////////////// |
1419 | 1367 |
1420 llvm::Value* DtoLoad(llvm::Value* src) | 1368 LLValue* DtoLoad(LLValue* src, const char* name) |
1421 { | 1369 { |
1422 llvm::Value* ld = gIR->ir->CreateLoad(src,"tmp"); | 1370 LLValue* ld = gIR->ir->CreateLoad(src, name ? name : "tmp"); |
1423 //ld->setVolatile(gIR->func()->inVolatile); | 1371 //ld->setVolatile(gIR->func()->inVolatile); |
1424 return ld; | 1372 return ld; |
1425 } | 1373 } |
1426 | 1374 |
1427 void DtoStore(llvm::Value* src, llvm::Value* dst) | 1375 void DtoStore(LLValue* src, LLValue* dst) |
1428 { | 1376 { |
1429 llvm::Value* st = gIR->ir->CreateStore(src,dst); | 1377 LLValue* st = gIR->ir->CreateStore(src,dst); |
1430 //st->setVolatile(gIR->func()->inVolatile); | 1378 //st->setVolatile(gIR->func()->inVolatile); |
1431 } | 1379 } |
1432 | 1380 |
1433 bool DtoCanLoad(llvm::Value* ptr) | 1381 bool DtoCanLoad(LLValue* ptr) |
1434 { | 1382 { |
1435 if (isaPointer(ptr->getType())) { | 1383 if (isaPointer(ptr->getType())) { |
1436 return ptr->getType()->getContainedType(0)->isFirstClassType(); | 1384 return ptr->getType()->getContainedType(0)->isFirstClassType(); |
1437 } | 1385 } |
1438 return false; | 1386 return false; |
1439 } | 1387 } |
1440 | 1388 |
1441 ////////////////////////////////////////////////////////////////////////////////////////// | 1389 ////////////////////////////////////////////////////////////////////////////////////////// |
1442 | 1390 |
1443 llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t, const char* name) | 1391 LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name) |
1444 { | 1392 { |
1445 if (v->getType() == t) | 1393 if (v->getType() == t) |
1446 return v; | 1394 return v; |
1447 return gIR->ir->CreateBitCast(v, t, name ? name : "tmp"); | 1395 return gIR->ir->CreateBitCast(v, t, name ? name : "tmp"); |
1448 } | 1396 } |
1449 | 1397 |
1450 ////////////////////////////////////////////////////////////////////////////////////////// | 1398 ////////////////////////////////////////////////////////////////////////////////////////// |
1451 | 1399 |
1452 const llvm::PointerType* isaPointer(llvm::Value* v) | 1400 const llvm::PointerType* isaPointer(LLValue* v) |
1453 { | 1401 { |
1454 return llvm::dyn_cast<llvm::PointerType>(v->getType()); | 1402 return llvm::dyn_cast<llvm::PointerType>(v->getType()); |
1455 } | 1403 } |
1456 | 1404 |
1457 const llvm::PointerType* isaPointer(const llvm::Type* t) | 1405 const llvm::PointerType* isaPointer(const LLType* t) |
1458 { | 1406 { |
1459 return llvm::dyn_cast<llvm::PointerType>(t); | 1407 return llvm::dyn_cast<llvm::PointerType>(t); |
1460 } | 1408 } |
1461 | 1409 |
1462 const llvm::ArrayType* isaArray(llvm::Value* v) | 1410 const llvm::ArrayType* isaArray(LLValue* v) |
1463 { | 1411 { |
1464 return llvm::dyn_cast<llvm::ArrayType>(v->getType()); | 1412 return llvm::dyn_cast<llvm::ArrayType>(v->getType()); |
1465 } | 1413 } |
1466 | 1414 |
1467 const llvm::ArrayType* isaArray(const llvm::Type* t) | 1415 const llvm::ArrayType* isaArray(const LLType* t) |
1468 { | 1416 { |
1469 return llvm::dyn_cast<llvm::ArrayType>(t); | 1417 return llvm::dyn_cast<llvm::ArrayType>(t); |
1470 } | 1418 } |
1471 | 1419 |
1472 const llvm::StructType* isaStruct(llvm::Value* v) | 1420 const llvm::StructType* isaStruct(LLValue* v) |
1473 { | 1421 { |
1474 return llvm::dyn_cast<llvm::StructType>(v->getType()); | 1422 return llvm::dyn_cast<llvm::StructType>(v->getType()); |
1475 } | 1423 } |
1476 | 1424 |
1477 const llvm::StructType* isaStruct(const llvm::Type* t) | 1425 const llvm::StructType* isaStruct(const LLType* t) |
1478 { | 1426 { |
1479 return llvm::dyn_cast<llvm::StructType>(t); | 1427 return llvm::dyn_cast<llvm::StructType>(t); |
1480 } | 1428 } |
1481 | 1429 |
1482 llvm::Constant* isaConstant(llvm::Value* v) | 1430 LLConstant* isaConstant(LLValue* v) |
1483 { | 1431 { |
1484 return llvm::dyn_cast<llvm::Constant>(v); | 1432 return llvm::dyn_cast<llvm::Constant>(v); |
1485 } | 1433 } |
1486 | 1434 |
1487 llvm::ConstantInt* isaConstantInt(llvm::Value* v) | 1435 llvm::ConstantInt* isaConstantInt(LLValue* v) |
1488 { | 1436 { |
1489 return llvm::dyn_cast<llvm::ConstantInt>(v); | 1437 return llvm::dyn_cast<llvm::ConstantInt>(v); |
1490 } | 1438 } |
1491 | 1439 |
1492 llvm::Argument* isaArgument(llvm::Value* v) | 1440 llvm::Argument* isaArgument(LLValue* v) |
1493 { | 1441 { |
1494 return llvm::dyn_cast<llvm::Argument>(v); | 1442 return llvm::dyn_cast<llvm::Argument>(v); |
1495 } | 1443 } |
1496 | 1444 |
1497 llvm::GlobalVariable* isaGlobalVar(llvm::Value* v) | 1445 llvm::GlobalVariable* isaGlobalVar(LLValue* v) |
1498 { | 1446 { |
1499 return llvm::dyn_cast<llvm::GlobalVariable>(v); | 1447 return llvm::dyn_cast<llvm::GlobalVariable>(v); |
1500 } | 1448 } |
1501 | 1449 |
1502 ////////////////////////////////////////////////////////////////////////////////////////// | 1450 ////////////////////////////////////////////////////////////////////////////////////////// |
1503 | 1451 |
1504 const llvm::PointerType* getPtrToType(const llvm::Type* t) | 1452 const llvm::PointerType* getPtrToType(const LLType* t) |
1505 { | 1453 { |
1506 return llvm::PointerType::get(t, 0); | 1454 return llvm::PointerType::get(t, 0); |
1507 } | 1455 } |
1508 | 1456 |
1509 const llvm::PointerType* getVoidPtrType() | 1457 const llvm::PointerType* getVoidPtrType() |
1510 { | 1458 { |
1511 return getPtrToType(llvm::Type::Int8Ty); | 1459 return getPtrToType(llvm::Type::Int8Ty); |
1512 } | 1460 } |
1513 | 1461 |
1514 llvm::ConstantPointerNull* getNullPtr(const llvm::Type* t) | 1462 llvm::ConstantPointerNull* getNullPtr(const LLType* t) |
1515 { | 1463 { |
1516 const llvm::PointerType* pt = llvm::cast<llvm::PointerType>(t); | 1464 const llvm::PointerType* pt = llvm::cast<llvm::PointerType>(t); |
1517 return llvm::ConstantPointerNull::get(pt); | 1465 return llvm::ConstantPointerNull::get(pt); |
1518 } | 1466 } |
1519 | 1467 |
1520 ////////////////////////////////////////////////////////////////////////////////////////// | 1468 ////////////////////////////////////////////////////////////////////////////////////////// |
1521 | 1469 |
1522 size_t getTypeBitSize(const llvm::Type* t) | 1470 size_t getTypeBitSize(const LLType* t) |
1523 { | 1471 { |
1524 return gTargetData->getTypeSizeInBits(t); | 1472 return gTargetData->getTypeSizeInBits(t); |
1525 } | 1473 } |
1526 | 1474 |
1527 size_t getTypeStoreSize(const llvm::Type* t) | 1475 size_t getTypeStoreSize(const LLType* t) |
1528 { | 1476 { |
1529 return gTargetData->getTypeStoreSize(t); | 1477 return gTargetData->getTypeStoreSize(t); |
1530 } | 1478 } |
1531 | 1479 |
1532 size_t getABITypeSize(const llvm::Type* t) | 1480 size_t getABITypeSize(const LLType* t) |
1533 { | 1481 { |
1534 return gTargetData->getABITypeSize(t); | 1482 return gTargetData->getABITypeSize(t); |
1535 } | 1483 } |
1536 | 1484 |
1537 ////////////////////////////////////////////////////////////////////////////////////////// | 1485 ////////////////////////////////////////////////////////////////////////////////////////// |
1546 return false; | 1494 return false; |
1547 } | 1495 } |
1548 | 1496 |
1549 ////////////////////////////////////////////////////////////////////////////////////////// | 1497 ////////////////////////////////////////////////////////////////////////////////////////// |
1550 | 1498 |
1551 void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type* t) | 1499 void DtoLazyStaticInit(bool istempl, LLValue* gvar, Initializer* init, Type* t) |
1552 { | 1500 { |
1553 // create a flag to make sure initialization only happens once | 1501 // create a flag to make sure initialization only happens once |
1554 llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage; | 1502 llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage; |
1555 std::string gflagname(gvar->getName()); | 1503 std::string gflagname(gvar->getName()); |
1556 gflagname.append("__initflag"); | 1504 gflagname.append("__initflag"); |
1558 | 1506 |
1559 // check flag and do init if not already done | 1507 // check flag and do init if not already done |
1560 llvm::BasicBlock* oldend = gIR->scopeend(); | 1508 llvm::BasicBlock* oldend = gIR->scopeend(); |
1561 llvm::BasicBlock* initbb = llvm::BasicBlock::Create("ifnotinit",gIR->topfunc(),oldend); | 1509 llvm::BasicBlock* initbb = llvm::BasicBlock::Create("ifnotinit",gIR->topfunc(),oldend); |
1562 llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend); | 1510 llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend); |
1563 llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); | 1511 LLValue* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); |
1564 gIR->ir->CreateCondBr(cond, initbb, endinitbb); | 1512 gIR->ir->CreateCondBr(cond, initbb, endinitbb); |
1565 gIR->scope() = IRScope(initbb,endinitbb); | 1513 gIR->scope() = IRScope(initbb,endinitbb); |
1566 DValue* ie = DtoInitializer(init); | 1514 DValue* ie = DtoInitializer(init); |
1567 if (!ie->inPlace()) { | 1515 if (!ie->inPlace()) { |
1568 DValue* dst = new DVarValue(t, gvar, true); | 1516 DValue* dst = new DVarValue(t, gvar, true); |
1671 Logger::println("* DtoConstInitGlobal(%s)", vd->toChars()); | 1619 Logger::println("* DtoConstInitGlobal(%s)", vd->toChars()); |
1672 LOG_SCOPE; | 1620 LOG_SCOPE; |
1673 | 1621 |
1674 bool emitRTstaticInit = false; | 1622 bool emitRTstaticInit = false; |
1675 | 1623 |
1676 llvm::Constant* _init = 0; | 1624 LLConstant* _init = 0; |
1677 if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) { | 1625 if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) { |
1678 _init = DtoConstInitializer(vd->type, NULL); | 1626 _init = DtoConstInitializer(vd->type, NULL); |
1679 emitRTstaticInit = true; | 1627 emitRTstaticInit = true; |
1680 } | 1628 } |
1681 else { | 1629 else { |
1682 _init = DtoConstInitializer(vd->type, vd->init); | 1630 _init = DtoConstInitializer(vd->type, vd->init); |
1683 } | 1631 } |
1684 | 1632 |
1685 const llvm::Type* _type = DtoType(vd->type); | 1633 const LLType* _type = DtoType(vd->type); |
1686 Type* t = DtoDType(vd->type); | 1634 Type* t = DtoDType(vd->type); |
1687 | 1635 |
1688 //Logger::cout() << "initializer: " << *_init << '\n'; | 1636 //Logger::cout() << "initializer: " << *_init << '\n'; |
1689 if (_type != _init->getType()) { | 1637 if (_type != _init->getType()) { |
1690 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; | 1638 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; |
1886 { | 1834 { |
1887 if (gIR->interfaceInfoType) | 1835 if (gIR->interfaceInfoType) |
1888 return gIR->interfaceInfoType; | 1836 return gIR->interfaceInfoType; |
1889 | 1837 |
1890 // build interface info type | 1838 // build interface info type |
1891 std::vector<const llvm::Type*> types; | 1839 std::vector<const LLType*> types; |
1892 // ClassInfo classinfo | 1840 // ClassInfo classinfo |
1893 ClassDeclaration* cd2 = ClassDeclaration::classinfo; | 1841 ClassDeclaration* cd2 = ClassDeclaration::classinfo; |
1894 DtoResolveClass(cd2); | 1842 DtoResolveClass(cd2); |
1895 types.push_back(getPtrToType(cd2->type->ir.type->get())); | 1843 types.push_back(getPtrToType(cd2->type->ir.type->get())); |
1896 // void*[] vtbl | 1844 // void*[] vtbl |
1897 std::vector<const llvm::Type*> vtbltypes; | 1845 std::vector<const LLType*> vtbltypes; |
1898 vtbltypes.push_back(DtoSize_t()); | 1846 vtbltypes.push_back(DtoSize_t()); |
1899 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); | 1847 const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); |
1900 vtbltypes.push_back(byteptrptrty); | 1848 vtbltypes.push_back(byteptrptrty); |
1901 types.push_back(llvm::StructType::get(vtbltypes)); | 1849 types.push_back(llvm::StructType::get(vtbltypes)); |
1902 // int offset | 1850 // int offset |
1903 types.push_back(llvm::Type::Int32Ty); | 1851 types.push_back(llvm::Type::Int32Ty); |
1904 // create type | 1852 // create type |
1907 return gIR->interfaceInfoType; | 1855 return gIR->interfaceInfoType; |
1908 } | 1856 } |
1909 | 1857 |
1910 ////////////////////////////////////////////////////////////////////////////////////////// | 1858 ////////////////////////////////////////////////////////////////////////////////////////// |
1911 | 1859 |
1912 llvm::Constant* DtoTypeInfoOf(Type* type) | 1860 LLConstant* DtoTypeInfoOf(Type* type, bool base) |
1913 { | 1861 { |
1914 const llvm::Type* typeinfotype = DtoType(Type::typeinfo->type); | 1862 const LLType* typeinfotype = DtoType(Type::typeinfo->type); |
1915 TypeInfoDeclaration* tidecl = type->getTypeInfoDeclaration(); | 1863 if (!type->vtinfo) |
1864 type->getTypeInfo(NULL); | |
1865 TypeInfoDeclaration* tidecl = type->vtinfo; | |
1916 DtoForceDeclareDsymbol(tidecl); | 1866 DtoForceDeclareDsymbol(tidecl); |
1917 assert(tidecl->ir.irGlobal != NULL); | 1867 assert(tidecl->ir.irGlobal != NULL); |
1918 llvm::Constant* c = isaConstant(tidecl->ir.irGlobal->value); | 1868 LLConstant* c = isaConstant(tidecl->ir.irGlobal->value); |
1919 assert(c != NULL); | 1869 assert(c != NULL); |
1920 return llvm::ConstantExpr::getBitCast(c, typeinfotype); | 1870 if (base) |
1921 } | 1871 return llvm::ConstantExpr::getBitCast(c, typeinfotype); |
1922 | 1872 return c; |
1923 | 1873 } |
1924 | 1874 |
1925 | 1875 |
1926 | 1876 |
1927 | 1877 |
1928 | 1878 |
1929 | 1879 |
1930 | 1880 |
1931 | 1881 |
1932 | 1882 |
1933 | 1883 |
1884 | |
1885 |