Mercurial > projects > ldc
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; |