comparison gen/arrays.cpp @ 244:a95056b3c996 trunk

[svn r261] Fixed debug info for integer and floating local variables, can now be inspected in GDB. Did a lot of smaller cleans up here and there. Replaced more llvm::Foo with LLFoo for common stuff. Split up tollvm.cpp.
author lindquist
date Mon, 09 Jun 2008 09:37:08 +0200
parents 9760f54af0b7
children 665b81613475
comparison
equal deleted inserted replaced
243:4d006f7b2ada 244:a95056b3c996
6 #include "declaration.h" 6 #include "declaration.h"
7 #include "init.h" 7 #include "init.h"
8 8
9 #include "gen/irstate.h" 9 #include "gen/irstate.h"
10 #include "gen/tollvm.h" 10 #include "gen/tollvm.h"
11 #include "gen/llvmhelpers.h"
11 #include "gen/arrays.h" 12 #include "gen/arrays.h"
12 #include "gen/runtime.h" 13 #include "gen/runtime.h"
13 #include "gen/logger.h" 14 #include "gen/logger.h"
14 #include "gen/dvalue.h" 15 #include "gen/dvalue.h"
15 16
16 ////////////////////////////////////////////////////////////////////////////////////////// 17 //////////////////////////////////////////////////////////////////////////////////////////
17 18
18 const llvm::StructType* DtoArrayType(Type* arrayTy) 19 const LLStructType* DtoArrayType(Type* arrayTy)
19 { 20 {
20 assert(arrayTy->next); 21 assert(arrayTy->next);
21 const LLType* elemty = DtoType(arrayTy->next); 22 const LLType* elemty = DtoType(arrayTy->next);
22 if (elemty == llvm::Type::VoidTy) 23 if (elemty == LLType::VoidTy)
23 elemty = llvm::Type::Int8Ty; 24 elemty = LLType::Int8Ty;
24 return llvm::StructType::get(DtoSize_t(), getPtrToType(elemty), 0); 25 return LLStructType::get(DtoSize_t(), getPtrToType(elemty), 0);
25 } 26 }
26 27
27 const llvm::StructType* DtoArrayType(const LLType* t) 28 const LLStructType* DtoArrayType(const LLType* t)
28 { 29 {
29 return llvm::StructType::get(DtoSize_t(), getPtrToType(t), 0); 30 return LLStructType::get(DtoSize_t(), getPtrToType(t), 0);
30 } 31 }
31 32
32 ////////////////////////////////////////////////////////////////////////////////////////// 33 //////////////////////////////////////////////////////////////////////////////////////////
33 34
34 const llvm::ArrayType* DtoStaticArrayType(Type* t) 35 const LLArrayType* DtoStaticArrayType(Type* t)
35 { 36 {
36 if (t->ir.type) 37 if (t->ir.type)
37 return isaArray(t->ir.type->get()); 38 return isaArray(t->ir.type->get());
38 39
39 assert(t->ty == Tsarray); 40 assert(t->ty == Tsarray);
41 42
42 const LLType* at = DtoType(t->next); 43 const LLType* at = DtoType(t->next);
43 44
44 TypeSArray* tsa = (TypeSArray*)t; 45 TypeSArray* tsa = (TypeSArray*)t;
45 assert(tsa->dim->type->isintegral()); 46 assert(tsa->dim->type->isintegral());
46 const llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger()); 47 const LLArrayType* arrty = LLArrayType::get(at,tsa->dim->toUInteger());
47 48
48 assert(!tsa->ir.type); 49 assert(!tsa->ir.type);
49 tsa->ir.type = new llvm::PATypeHolder(arrty); 50 tsa->ir.type = new LLPATypeHolder(arrty);
50 return arrty; 51 return arrty;
51 } 52 }
52 53
53 ////////////////////////////////////////////////////////////////////////////////////////// 54 //////////////////////////////////////////////////////////////////////////////////////////
54 55
55 void DtoSetArrayToNull(LLValue* v) 56 void DtoSetArrayToNull(LLValue* v)
56 { 57 {
57 Logger::println("DtoSetArrayToNull"); 58 Logger::println("DtoSetArrayToNull");
58 LOG_SCOPE; 59 LOG_SCOPE;
59 60
60 LLValue* len = DtoGEPi(v,0,0,"tmp",gIR->scopebb()); 61 LLValue* len = DtoGEPi(v,0,0);
61 LLValue* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false); 62 LLValue* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false);
62 new llvm::StoreInst(zerolen, len, gIR->scopebb()); 63 DtoStore(zerolen, len);
63 64
64 LLValue* ptr = DtoGEPi(v,0,1,"tmp",gIR->scopebb()); 65 LLValue* ptr = DtoGEPi(v,0,1);
65 const llvm::PointerType* pty = isaPointer(ptr->getType()->getContainedType(0)); 66 const LLPointerType* pty = isaPointer(ptr->getType()->getContainedType(0));
66 LLValue* nullptr = llvm::ConstantPointerNull::get(pty); 67 LLValue* nullptr = llvm::ConstantPointerNull::get(pty);
67 new llvm::StoreInst(nullptr, ptr, gIR->scopebb()); 68 DtoStore(nullptr, ptr);
68 } 69 }
69 70
70 ////////////////////////////////////////////////////////////////////////////////////////// 71 //////////////////////////////////////////////////////////////////////////////////////////
71 72
72 void DtoArrayAssign(LLValue* dst, LLValue* src) 73 void DtoArrayAssign(LLValue* dst, LLValue* src)
75 LOG_SCOPE; 76 LOG_SCOPE;
76 77
77 assert(gIR); 78 assert(gIR);
78 if (dst->getType() == src->getType()) 79 if (dst->getType() == src->getType())
79 { 80 {
80 LLValue* ptr = DtoGEPi(src,0,0,"tmp",gIR->scopebb()); 81 LLValue* ptr = DtoGEPi(src,0,0);
81 LLValue* val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); 82 LLValue* val = DtoLoad(ptr);
82 ptr = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); 83 ptr = DtoGEPi(dst,0,0);
83 new llvm::StoreInst(val, ptr, gIR->scopebb()); 84 DtoStore(val, ptr);
84 85
85 ptr = DtoGEPi(src,0,1,"tmp",gIR->scopebb()); 86 ptr = DtoGEPi(src,0,1);
86 val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); 87 val = DtoLoad(ptr);
87 ptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb()); 88 ptr = DtoGEPi(dst,0,1);
88 new llvm::StoreInst(val, ptr, gIR->scopebb()); 89 DtoStore(val, ptr);
89 } 90 }
90 else 91 else
91 { 92 {
92 Logger::cout() << "array assignment type dont match: " << *dst->getType() << "\n\n" << *src->getType() << '\n'; 93 Logger::cout() << "array assignment type dont match: " << *dst->getType() << "\n\n" << *src->getType() << '\n';
93 const llvm::ArrayType* arrty = isaArray(src->getType()->getContainedType(0)); 94 const LLArrayType* arrty = isaArray(src->getType()->getContainedType(0));
94 if (!arrty) 95 if (!arrty)
95 { 96 {
96 Logger::cout() << "invalid: " << *src << '\n'; 97 Logger::cout() << "invalid: " << *src << '\n';
97 assert(0); 98 assert(0);
98 } 99 }
99 const LLType* dstty = getPtrToType(arrty->getElementType()); 100 const LLType* dstty = getPtrToType(arrty->getElementType());
100 101
101 LLValue* dstlen = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); 102 LLValue* dstlen = DtoGEPi(dst,0,0);
102 LLValue* srclen = DtoConstSize_t(arrty->getNumElements()); 103 LLValue* srclen = DtoConstSize_t(arrty->getNumElements());
103 new llvm::StoreInst(srclen, dstlen, gIR->scopebb()); 104 DtoStore(srclen, dstlen);
104 105
105 LLValue* dstptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb()); 106 LLValue* dstptr = DtoGEPi(dst,0,1);
106 LLValue* srcptr = DtoBitCast(src, dstty); 107 LLValue* srcptr = DtoBitCast(src, dstty);
107 new llvm::StoreInst(srcptr, dstptr, gIR->scopebb()); 108 DtoStore(srcptr, dstptr);
108 } 109 }
109 } 110 }
110 111
111 ////////////////////////////////////////////////////////////////////////////////////////// 112 //////////////////////////////////////////////////////////////////////////////////////////
112 113
113 void DtoArrayInit(LLValue* l, LLValue* r) 114 void DtoArrayInit(LLValue* l, LLValue* r)
114 { 115 {
115 Logger::println("DtoArrayInit"); 116 Logger::println("DtoArrayInit");
116 LOG_SCOPE; 117 LOG_SCOPE;
117 118
118 const llvm::PointerType* ptrty = isaPointer(l->getType()); 119 const LLPointerType* ptrty = isaPointer(l->getType());
119 const LLType* t = ptrty->getContainedType(0); 120 const LLType* t = ptrty->getContainedType(0);
120 const llvm::ArrayType* arrty = isaArray(t); 121 const LLArrayType* arrty = isaArray(t);
121 if (arrty) 122 if (arrty)
122 { 123 {
123 LLValue* ptr = DtoGEPi(l,0,0,"tmp",gIR->scopebb()); 124 LLValue* ptr = DtoGEPi(l,0,0);
124 LLValue* dim = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); 125 LLValue* dim = DtoConstSize_t(arrty->getNumElements());
125 DtoArrayInit(ptr, dim, r); 126 DtoArrayInit(ptr, dim, r);
126 } 127 }
127 else if (isaStruct(t)) 128 else if (isaStruct(t))
128 { 129 {
129 LLValue* dim = DtoLoad(DtoGEPi(l, 0,0, "tmp")); 130 LLValue* dim = DtoLoad(DtoGEPi(l, 0,0));
130 LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1, "tmp")); 131 LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1));
131 DtoArrayInit(ptr, dim, r); 132 DtoArrayInit(ptr, dim, r);
132 } 133 }
133 else 134 else
134 assert(0); 135 assert(0);
135 } 136 }
138 139
139 typedef const LLType* constLLVMTypeP; 140 typedef const LLType* constLLVMTypeP;
140 141
141 static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty) 142 static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty)
142 { 143 {
143 if (const llvm::ArrayType* arrty = isaArray(pt)) { 144 if (const LLArrayType* arrty = isaArray(pt)) {
144 size_t n = checkRectArrayInit(arrty->getElementType(), finalty); 145 size_t n = checkRectArrayInit(arrty->getElementType(), finalty);
145 size_t ne = arrty->getNumElements(); 146 size_t ne = arrty->getNumElements();
146 if (n) return n * ne; 147 if (n) return n * ne;
147 return ne; 148 return ne;
148 } 149 }
178 nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp"); 179 nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp");
179 DtoMemSetZero(ptr,nbytes); 180 DtoMemSetZero(ptr,nbytes);
180 return; 181 return;
181 } 182 }
182 else { 183 else {
183 ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(llvm::Type::Int8Ty), "tmp"); 184 ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(LLType::Int8Ty), "tmp");
184 } 185 }
185 } 186 }
186 else { 187 else {
187 assert(t == pt); 188 assert(t == pt);
188 } 189 }
201 args.push_back(DtoConstSize_t(aggrsz)); 202 args.push_back(DtoConstSize_t(aggrsz));
202 } 203 }
203 else if (isaPointer(t)) { 204 else if (isaPointer(t)) {
204 funcname = "_d_array_init_pointer"; 205 funcname = "_d_array_init_pointer";
205 206
206 const LLType* dstty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); 207 const LLType* dstty = getPtrToType(getPtrToType(LLType::Int8Ty));
207 if (args[0]->getType() != dstty) 208 if (args[0]->getType() != dstty)
208 args[0] = DtoBitCast(args[0],dstty); 209 args[0] = DtoBitCast(args[0],dstty);
209 210
210 const LLType* valty = getPtrToType(llvm::Type::Int8Ty); 211 const LLType* valty = getPtrToType(LLType::Int8Ty);
211 if (args[2]->getType() != valty) 212 if (args[2]->getType() != valty)
212 args[2] = DtoBitCast(args[2],valty); 213 args[2] = DtoBitCast(args[2],valty);
213 } 214 }
214 else if (t == llvm::Type::Int1Ty) { 215 else if (t == LLType::Int1Ty) {
215 funcname = "_d_array_init_i1"; 216 funcname = "_d_array_init_i1";
216 } 217 }
217 else if (t == llvm::Type::Int8Ty) { 218 else if (t == LLType::Int8Ty) {
218 funcname = "_d_array_init_i8"; 219 funcname = "_d_array_init_i8";
219 } 220 }
220 else if (t == llvm::Type::Int16Ty) { 221 else if (t == LLType::Int16Ty) {
221 funcname = "_d_array_init_i16"; 222 funcname = "_d_array_init_i16";
222 } 223 }
223 else if (t == llvm::Type::Int32Ty) { 224 else if (t == LLType::Int32Ty) {
224 funcname = "_d_array_init_i32"; 225 funcname = "_d_array_init_i32";
225 } 226 }
226 else if (t == llvm::Type::Int64Ty) { 227 else if (t == LLType::Int64Ty) {
227 funcname = "_d_array_init_i64"; 228 funcname = "_d_array_init_i64";
228 } 229 }
229 else if (t == llvm::Type::FloatTy) { 230 else if (t == LLType::FloatTy) {
230 funcname = "_d_array_init_float"; 231 funcname = "_d_array_init_float";
231 } 232 }
232 else if (t == llvm::Type::DoubleTy) { 233 else if (t == LLType::DoubleTy) {
233 funcname = "_d_array_init_double"; 234 funcname = "_d_array_init_double";
234 } 235 }
235 else { 236 else {
236 Logger::cout() << *ptr->getType() << " = " << *val->getType() << '\n'; 237 Logger::cout() << *ptr->getType() << " = " << *val->getType() << '\n';
237 assert(0); 238 assert(0);
238 } 239 }
239 240
240 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname); 241 LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
241 assert(fn); 242 assert(fn);
242 Logger::cout() << "calling array init function: " << *fn <<'\n'; 243 Logger::cout() << "calling array init function: " << *fn <<'\n';
243 llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); 244 llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb());
244 call->setCallingConv(llvm::CallingConv::C); 245 call->setCallingConv(llvm::CallingConv::C);
245 } 246 }
246 247
247 ////////////////////////////////////////////////////////////////////////////////////////// 248 //////////////////////////////////////////////////////////////////////////////////////////
248 249
249 void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr) 250 void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
250 { 251 {
251 Logger::println("DtoSetArray"); 252 Logger::println("SetArray");
252 LOG_SCOPE; 253 DtoStore(dim, DtoGEPi(arr,0,0));
253 254 DtoStore(ptr, DtoGEPi(arr,0,1));
254 Logger::cout() << "arr = " << *arr << '\n';
255 Logger::cout() << "dim = " << *dim << '\n';
256 Logger::cout() << "ptr = " << *ptr << '\n';
257
258 const llvm::StructType* st = isaStruct(arr->getType()->getContainedType(0));
259
260 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
261 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
262
263 LLValue* arrdim = DtoGEP(arr,zero,zero,"tmp",gIR->scopebb());
264 Logger::cout() << "arrdim = " << *arrdim << '\n';
265 new llvm::StoreInst(dim, arrdim, gIR->scopebb());
266
267 LLValue* arrptr = DtoGEP(arr,zero,one,"tmp",gIR->scopebb());
268 Logger::cout() << "arrptr = " << *arrptr << '\n';
269 new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
270 } 255 }
271 256
272 ////////////////////////////////////////////////////////////////////////////////////////// 257 //////////////////////////////////////////////////////////////////////////////////////////
273 LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) 258 LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit)
274 { 259 {
324 //integer_t k = idx->toInteger(); 309 //integer_t k = idx->toInteger();
325 //Logger::println("getting value for exp: %s | %s", idx->toChars(), arrnext->toChars()); 310 //Logger::println("getting value for exp: %s | %s", idx->toChars(), arrnext->toChars());
326 LLConstant* cc = idx->toConstElem(gIR); 311 LLConstant* cc = idx->toConstElem(gIR);
327 Logger::println("value gotten"); 312 Logger::println("value gotten");
328 assert(cc != NULL); 313 assert(cc != NULL);
329 llvm::ConstantInt* ci = llvm::dyn_cast<llvm::ConstantInt>(cc); 314 LLConstantInt* ci = llvm::dyn_cast<LLConstantInt>(cc);
330 assert(ci != NULL); 315 assert(ci != NULL);
331 uint64_t k = ci->getZExtValue(); 316 uint64_t k = ci->getZExtValue();
332 if (i == k) 317 if (i == k)
333 { 318 {
334 init = (Initializer*)arrinit->value.data[j]; 319 init = (Initializer*)arrinit->value.data[j];
354 inits[i] = v; 339 inits[i] = v;
355 Logger::cout() << "llval: " << *v << '\n'; 340 Logger::cout() << "llval: " << *v << '\n';
356 } 341 }
357 342
358 Logger::println("building constant array"); 343 Logger::println("building constant array");
359 const llvm::ArrayType* arrty = llvm::ArrayType::get(elemty,tdim); 344 const LLArrayType* arrty = LLArrayType::get(elemty,tdim);
360 LLConstant* constarr = llvm::ConstantArray::get(arrty, inits); 345 LLConstant* constarr = LLConstantArray::get(arrty, inits);
361 346
362 if (arrinittype->ty == Tsarray) 347 if (arrinittype->ty == Tsarray)
363 return constarr; 348 return constarr;
364 else 349 else
365 assert(arrinittype->ty == Tarray); 350 assert(arrinittype->ty == Tarray);
366 351
367 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrty,true,llvm::GlobalValue::InternalLinkage,constarr,"constarray",gIR->module); 352 LLGlobalVariable* gvar = new LLGlobalVariable(arrty,true,LLGlobalValue::InternalLinkage,constarr,"constarray",gIR->module);
368 LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; 353 LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
369 LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); 354 LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
370 return DtoConstSlice(DtoConstSize_t(tdim),gep); 355 return DtoConstSlice(DtoConstSize_t(tdim),gep);
371 } 356 }
372 357
388 else { 373 else {
389 sz = llvm::BinaryOperator::createMul(elemsz,e->len,"tmp",gIR->scopebb()); 374 sz = llvm::BinaryOperator::createMul(elemsz,e->len,"tmp",gIR->scopebb());
390 } 375 }
391 } 376 }
392 else if (isaArray(t)) { 377 else if (isaArray(t)) {
393 ret = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb()); 378 ret = DtoGEPi(e->ptr, 0, 0);
394 379
395 size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0)); 380 size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
396 llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false); 381 llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
397 382
398 size_t numelements = isaArray(t)->getNumElements(); 383 size_t numelements = isaArray(t)->getNumElements();
399 llvm::ConstantInt* nelems = llvm::ConstantInt::get(DtoSize_t(), numelements, false); 384 llvm::ConstantInt* nelems = llvm::ConstantInt::get(DtoSize_t(), numelements, false);
400 385
401 sz = llvm::ConstantExpr::getMul(elemsz, nelems); 386 sz = llvm::ConstantExpr::getMul(elemsz, nelems);
402 } 387 }
403 else if (isaStruct(t)) { 388 else if (isaStruct(t)) {
404 ret = DtoGEPi(e->ptr, 0, 1, "tmp", gIR->scopebb()); 389 ret = DtoGEPi(e->ptr, 0, 1);
405 ret = new llvm::LoadInst(ret, "tmp", gIR->scopebb()); 390 ret = DtoLoad(ret);
406 391
407 size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0)); 392 size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0));
408 llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false); 393 llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false);
409 394
410 LLValue* len = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb()); 395 LLValue* len = DtoGEPi(e->ptr, 0, 0);
411 len = new llvm::LoadInst(len, "tmp", gIR->scopebb()); 396 len = DtoLoad(len);
412 sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb()); 397 sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb());
413 } 398 }
414 else { 399 else {
415 assert(0); 400 assert(0);
416 } 401 }
418 } 403 }
419 404
420 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src) 405 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src)
421 { 406 {
422 Logger::println("ArrayCopySlices"); 407 Logger::println("ArrayCopySlices");
423 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); 408
409 LLValue *sz1,*sz2;
410 LLValue* dstarr = get_slice_ptr(dst,sz1);
411 LLValue* srcarr = get_slice_ptr(src,sz2);
412
413 DtoMemCpy(dstarr, srcarr, sz1);
414 }
415
416 void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src)
417 {
418 Logger::println("ArrayCopyToSlice");
424 419
425 LLValue* sz1; 420 LLValue* sz1;
426 LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty); 421 LLValue* dstarr = get_slice_ptr(dst,sz1);
427 422 LLValue* srcarr = DtoArrayPtr(src);
428 LLValue* sz2; 423
429 LLValue* srcarr = DtoBitCast(get_slice_ptr(src,sz2),arrty); 424 DtoMemCpy(dstarr, srcarr, sz1);
430
431 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
432 LLSmallVector<LLValue*, 4> llargs(4);
433 llargs[0] = dstarr;
434 llargs[1] = srcarr;
435 llargs[2] = sz1;
436 llargs[3] = DtoConstInt(0);
437
438 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
439 }
440
441 void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src)
442 {
443 Logger::println("ArrayCopyToSlice");
444 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
445
446 LLValue* sz1;
447 LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty);
448 LLValue* srcarr = DtoBitCast(DtoArrayPtr(src),arrty);
449
450 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
451 LLSmallVector<LLValue*, 4> llargs(4);
452 llargs[0] = dstarr;
453 llargs[1] = srcarr;
454 llargs[2] = sz1;
455 llargs[3] = DtoConstInt(0);
456
457 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
458 } 425 }
459 426
460 ////////////////////////////////////////////////////////////////////////////////////////// 427 //////////////////////////////////////////////////////////////////////////////////////////
461 void DtoStaticArrayCopy(LLValue* dst, LLValue* src) 428 void DtoStaticArrayCopy(LLValue* dst, LLValue* src)
462 { 429 {
463 Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n'; 430 Logger::println("StaticArrayCopy");
464 assert(dst->getType() == src->getType()); 431
465 size_t arrsz = getABITypeSize(dst->getType()->getContainedType(0)); 432 size_t n = getABITypeSize(dst->getType()->getContainedType(0));
466 LLValue* n = llvm::ConstantInt::get(DtoSize_t(), arrsz, false); 433 DtoMemCpy(dst, src, DtoConstSize_t(n));
467
468 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty);
469 LLValue* dstarr = DtoBitCast(dst,arrty);
470 LLValue* srcarr = DtoBitCast(src,arrty);
471
472 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
473 LLSmallVector<LLValue*,4> llargs(4);
474 llargs[0] = dstarr;
475 llargs[1] = srcarr;
476 llargs[2] = n;
477 llargs[3] = DtoConstInt(0);
478
479 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
480 } 434 }
481 435
482 ////////////////////////////////////////////////////////////////////////////////////////// 436 //////////////////////////////////////////////////////////////////////////////////////////
483 LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) 437 LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr)
484 { 438 {
499 assert(DtoType(dim->getType()) == DtoSize_t()); 453 assert(DtoType(dim->getType()) == DtoSize_t());
500 LLValue* arrayLen = dim->getRVal(); 454 LLValue* arrayLen = dim->getRVal();
501 455
502 // get runtime function 456 // get runtime function
503 bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit(); 457 bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
504 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" ); 458 LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
505 459
506 // call allocator 460 // call allocator
507 LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem"); 461 LLValue* newptr = gIR->ir->CreateCall2(fn, arrayTypeInfo, arrayLen, ".gc_mem");
508 462
509 // cast to wanted type 463 // cast to wanted type
536 490
537 // decide on what runtime function to call based on whether the type is zero initialized 491 // decide on what runtime function to call based on whether the type is zero initialized
538 bool zeroInit = arrayType->toBasetype()->next->isZeroInit(); 492 bool zeroInit = arrayType->toBasetype()->next->isZeroInit();
539 493
540 // call runtime 494 // call runtime
541 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" ); 495 LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" );
542 496
543 LLSmallVector<LLValue*,4> args; 497 LLSmallVector<LLValue*,4> args;
544 args.push_back(DtoTypeInfoOf(arrayType)); 498 args.push_back(DtoTypeInfoOf(arrayType));
545 args.push_back(newdim->getRVal()); 499 args.push_back(newdim->getRVal());
546 args.push_back(DtoArrayLen(array)); 500 args.push_back(DtoArrayLen(array));
723 ////////////////////////////////////////////////////////////////////////////////////////// 677 //////////////////////////////////////////////////////////////////////////////////////////
724 // helper for eq and cmp 678 // helper for eq and cmp
725 static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti) 679 static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti)
726 { 680 {
727 Logger::println("comparing arrays"); 681 Logger::println("comparing arrays");
728 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, func); 682 LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, func);
729 assert(fn); 683 assert(fn);
730 684
731 LLValue* lmem; 685 LLValue* lmem;
732 LLValue* rmem; 686 LLValue* rmem;
733 687
886 LLSmallVector<LLValue*, 3> args; 840 LLSmallVector<LLValue*, 3> args;
887 args.push_back(len); 841 args.push_back(len);
888 args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false)); 842 args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false));
889 args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false)); 843 args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false));
890 844
891 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len"); 845 LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
892 return llvm::CallInst::Create(fn, args.begin(), args.end(), "tmp", gIR->scopebb()); 846 return llvm::CallInst::Create(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
893 } 847 }
894 848
895 ////////////////////////////////////////////////////////////////////////////////////////// 849 //////////////////////////////////////////////////////////////////////////////////////////
896 LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r) 850 LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r)
897 { 851 {
898 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; 852 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
899 853
900 if (r == NULL) { 854 if (r == NULL) {
901 LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); 855 LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp");
902 LLValue* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0); 856 LLValue* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0);
903 LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); 857 LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
904 858
905 LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); 859 LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp");
906 const llvm::PointerType* pty = isaPointer(lp->getType()); 860 const LLPointerType* pty = isaPointer(lp->getType());
907 LLValue* rp = llvm::ConstantPointerNull::get(pty); 861 LLValue* rp = llvm::ConstantPointerNull::get(pty);
908 LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); 862 LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
909 863
910 LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp"); 864 LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
911 return b; 865 return b;
912 } 866 }
913 else { 867 else {
914 assert(l->getType() == r->getType()); 868 assert(l->getType() == r->getType());
915 869
916 LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); 870 LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0),"tmp");
917 LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0, "tmp"),"tmp"); 871 LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0),"tmp");
918 LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); 872 LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
919 873
920 LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); 874 LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1),"tmp");
921 LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1, "tmp"),"tmp"); 875 LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1),"tmp");
922 LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); 876 LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
923 877
924 LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp"); 878 LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp");
925 return b; 879 return b;
926 } 880 }
927 } 881 }
928 882
929 ////////////////////////////////////////////////////////////////////////////////////////// 883 //////////////////////////////////////////////////////////////////////////////////////////
930 LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c) 884 LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c)
931 { 885 {
932 const llvm::ArrayType* at = isaArray(t); 886 const LLArrayType* at = isaArray(t);
933 assert(at); 887 assert(at);
934 888
935 if (isaArray(at->getElementType())) 889 if (isaArray(at->getElementType()))
936 { 890 {
937 c = DtoConstStaticArray(at->getElementType(), c); 891 c = DtoConstStaticArray(at->getElementType(), c);
954 if (t->ty == Tarray) { 908 if (t->ty == Tarray) {
955 if (DSliceValue* s = v->isSlice()) { 909 if (DSliceValue* s = v->isSlice()) {
956 if (s->len) { 910 if (s->len) {
957 return s->len; 911 return s->len;
958 } 912 }
959 const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0)); 913 const LLArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
960 if (arrTy) 914 if (arrTy)
961 return DtoConstSize_t(arrTy->getNumElements()); 915 return DtoConstSize_t(arrTy->getNumElements());
962 else 916 else
963 return DtoLoad(DtoGEPi(s->ptr, 0,0, "tmp")); 917 return DtoLoad(DtoGEPi(s->ptr, 0,0));
964 } 918 }
965 return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp")); 919 return DtoLoad(DtoGEPi(v->getRVal(), 0,0));
966 } 920 }
967 else if (t->ty == Tsarray) { 921 else if (t->ty == Tsarray) {
968 assert(!v->isSlice()); 922 assert(!v->isSlice());
969 LLValue* rv = v->getRVal(); 923 LLValue* rv = v->getRVal();
970 Logger::cout() << "casting: " << *rv << '\n'; 924 Logger::cout() << "casting: " << *rv << '\n';
971 const llvm::ArrayType* t = isaArray(rv->getType()->getContainedType(0)); 925 const LLArrayType* t = isaArray(rv->getType()->getContainedType(0));
972 return DtoConstSize_t(t->getNumElements()); 926 return DtoConstSize_t(t->getNumElements());
973 } 927 }
974 assert(0); 928 assert(0);
975 return 0; 929 return 0;
976 } 930 }
985 if (t->ty == Tarray) { 939 if (t->ty == Tarray) {
986 if (DSliceValue* s = v->isSlice()) { 940 if (DSliceValue* s = v->isSlice()) {
987 if (s->len) return s->ptr; 941 if (s->len) return s->ptr;
988 const LLType* t = s->ptr->getType()->getContainedType(0); 942 const LLType* t = s->ptr->getType()->getContainedType(0);
989 Logger::cout() << "ptr of full slice: " << *s->ptr << '\n'; 943 Logger::cout() << "ptr of full slice: " << *s->ptr << '\n';
990 const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0)); 944 const LLArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0));
991 if (arrTy) 945 if (arrTy)
992 return DtoGEPi(s->ptr, 0,0, "tmp"); 946 return DtoGEPi(s->ptr, 0,0);
993 else 947 else
994 return DtoLoad(DtoGEPi(s->ptr, 0,1, "tmp")); 948 return DtoLoad(DtoGEPi(s->ptr, 0,1));
995 } 949 }
996 return DtoLoad(DtoGEPi(v->getRVal(), 0,1, "tmp")); 950 return DtoLoad(DtoGEPi(v->getRVal(), 0,1));
997 } 951 }
998 else if (t->ty == Tsarray) { 952 else if (t->ty == Tsarray) {
999 return DtoGEPi(v->getRVal(), 0,0, "tmp"); 953 return DtoGEPi(v->getRVal(), 0,0);
1000 } 954 }
1001 assert(0); 955 assert(0);
1002 return 0; 956 return 0;
1003 } 957 }
1004 958
1026 rval = gIR->ir->CreateBitCast(rval, tolltype, "tmp"); 980 rval = gIR->ir->CreateBitCast(rval, tolltype, "tmp");
1027 } 981 }
1028 else if (totype->ty == Tarray) { 982 else if (totype->ty == Tarray) {
1029 Logger::cout() << "to array" << '\n'; 983 Logger::cout() << "to array" << '\n';
1030 const LLType* ptrty = DtoType(totype->next); 984 const LLType* ptrty = DtoType(totype->next);
1031 if (ptrty == llvm::Type::VoidTy) 985 if (ptrty == LLType::VoidTy)
1032 ptrty = llvm::Type::Int8Ty; 986 ptrty = LLType::Int8Ty;
1033 ptrty = getPtrToType(ptrty); 987 ptrty = getPtrToType(ptrty);
1034 988
1035 const LLType* ety = DtoType(fromtype->next); 989 const LLType* ety = DtoType(fromtype->next);
1036 if (ety == llvm::Type::VoidTy) 990 if (ety == LLType::VoidTy)
1037 ety = llvm::Type::Int8Ty; 991 ety = LLType::Int8Ty;
1038 992
1039 if (DSliceValue* usl = u->isSlice()) { 993 if (DSliceValue* usl = u->isSlice()) {
1040 Logger::println("from slice"); 994 Logger::println("from slice");
1041 Logger::cout() << "from: " << *usl->ptr << " to: " << *ptrty << '\n'; 995 Logger::cout() << "from: " << *usl->ptr << " to: " << *ptrty << '\n';
1042 rval = DtoBitCast(usl->ptr, ptrty); 996 rval = DtoBitCast(usl->ptr, ptrty);
1048 else { 1002 else {
1049 LLValue* uval = u->getRVal(); 1003 LLValue* uval = u->getRVal();
1050 if (fromtype->ty == Tsarray) { 1004 if (fromtype->ty == Tsarray) {
1051 Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; 1005 Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
1052 assert(isaPointer(uval->getType())); 1006 assert(isaPointer(uval->getType()));
1053 const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); 1007 const LLArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
1054 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); 1008 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
1055 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); 1009 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1056 rval = DtoBitCast(uval, ptrty); 1010 rval = DtoBitCast(uval, ptrty);
1057 } 1011 }
1058 else { 1012 else {
1059 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 1013 LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
1060 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); 1014 LLValue* one = llvm::ConstantInt::get(LLType::Int32Ty, 1, false);
1061 rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb()); 1015 rval2 = DtoGEP(uval,zero,zero);
1062 rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb()); 1016 rval2 = DtoLoad(rval2);
1063 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); 1017 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1064 1018
1065 rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb()); 1019 rval = DtoGEP(uval,zero,one);
1066 rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb()); 1020 rval = DtoLoad(rval);
1067 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n'; 1021 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n';
1068 rval = DtoBitCast(rval, ptrty); 1022 rval = DtoBitCast(rval, ptrty);
1069 } 1023 }
1070 } 1024 }
1071 isslice = true; 1025 isslice = true;