Mercurial > projects > ldc
comparison gen/arrays.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 | f66219e0d530 |
children | 0806379a5eca |
comparison
equal
deleted
inserted
replaced
212:4c2689d57ba4 | 213:7816aafeea3c |
---|---|
16 ////////////////////////////////////////////////////////////////////////////////////////// | 16 ////////////////////////////////////////////////////////////////////////////////////////// |
17 | 17 |
18 const llvm::StructType* DtoArrayType(Type* t) | 18 const llvm::StructType* DtoArrayType(Type* t) |
19 { | 19 { |
20 assert(t->next); | 20 assert(t->next); |
21 const llvm::Type* at = DtoType(t->next); | 21 const LLType* elemty = DtoType(t->next); |
22 const llvm::Type* arrty; | 22 if (elemty == llvm::Type::VoidTy) |
23 | 23 elemty = llvm::Type::Int8Ty; |
24 if (at == llvm::Type::VoidTy) { | 24 return llvm::StructType::get(DtoSize_t(), getPtrToType(elemty), 0); |
25 at = llvm::Type::Int8Ty; | |
26 } | |
27 arrty = getPtrToType(at); | |
28 | |
29 std::vector<const llvm::Type*> members; | |
30 if (global.params.is64bit) | |
31 members.push_back(llvm::Type::Int64Ty); | |
32 else | |
33 members.push_back(llvm::Type::Int32Ty); | |
34 | |
35 members.push_back(arrty); | |
36 | |
37 return llvm::StructType::get(members); | |
38 } | 25 } |
39 | 26 |
40 ////////////////////////////////////////////////////////////////////////////////////////// | 27 ////////////////////////////////////////////////////////////////////////////////////////// |
41 | 28 |
42 const llvm::ArrayType* DtoStaticArrayType(Type* t) | 29 const llvm::ArrayType* DtoStaticArrayType(Type* t) |
45 return isaArray(t->ir.type->get()); | 32 return isaArray(t->ir.type->get()); |
46 | 33 |
47 assert(t->ty == Tsarray); | 34 assert(t->ty == Tsarray); |
48 assert(t->next); | 35 assert(t->next); |
49 | 36 |
50 const llvm::Type* at = DtoType(t->next); | 37 const LLType* at = DtoType(t->next); |
51 | 38 |
52 TypeSArray* tsa = (TypeSArray*)t; | 39 TypeSArray* tsa = (TypeSArray*)t; |
53 assert(tsa->dim->type->isintegral()); | 40 assert(tsa->dim->type->isintegral()); |
54 const llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger()); | 41 const llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger()); |
55 | 42 |
58 return arrty; | 45 return arrty; |
59 } | 46 } |
60 | 47 |
61 ////////////////////////////////////////////////////////////////////////////////////////// | 48 ////////////////////////////////////////////////////////////////////////////////////////// |
62 | 49 |
63 void DtoSetArrayToNull(llvm::Value* v) | 50 void DtoSetArrayToNull(LLValue* v) |
64 { | 51 { |
65 Logger::println("DtoSetArrayToNull"); | 52 Logger::println("DtoSetArrayToNull"); |
66 LOG_SCOPE; | 53 LOG_SCOPE; |
67 | 54 |
68 llvm::Value* len = DtoGEPi(v,0,0,"tmp",gIR->scopebb()); | 55 LLValue* len = DtoGEPi(v,0,0,"tmp",gIR->scopebb()); |
69 llvm::Value* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false); | 56 LLValue* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false); |
70 new llvm::StoreInst(zerolen, len, gIR->scopebb()); | 57 new llvm::StoreInst(zerolen, len, gIR->scopebb()); |
71 | 58 |
72 llvm::Value* ptr = DtoGEPi(v,0,1,"tmp",gIR->scopebb()); | 59 LLValue* ptr = DtoGEPi(v,0,1,"tmp",gIR->scopebb()); |
73 const llvm::PointerType* pty = isaPointer(ptr->getType()->getContainedType(0)); | 60 const llvm::PointerType* pty = isaPointer(ptr->getType()->getContainedType(0)); |
74 llvm::Value* nullptr = llvm::ConstantPointerNull::get(pty); | 61 LLValue* nullptr = llvm::ConstantPointerNull::get(pty); |
75 new llvm::StoreInst(nullptr, ptr, gIR->scopebb()); | 62 new llvm::StoreInst(nullptr, ptr, gIR->scopebb()); |
76 } | 63 } |
77 | 64 |
78 ////////////////////////////////////////////////////////////////////////////////////////// | 65 ////////////////////////////////////////////////////////////////////////////////////////// |
79 | 66 |
80 void DtoArrayAssign(llvm::Value* dst, llvm::Value* src) | 67 void DtoArrayAssign(LLValue* dst, LLValue* src) |
81 { | 68 { |
82 Logger::println("DtoArrayAssign"); | 69 Logger::println("DtoArrayAssign"); |
83 LOG_SCOPE; | 70 LOG_SCOPE; |
84 | 71 |
85 assert(gIR); | 72 assert(gIR); |
86 if (dst->getType() == src->getType()) | 73 if (dst->getType() == src->getType()) |
87 { | 74 { |
88 llvm::Value* ptr = DtoGEPi(src,0,0,"tmp",gIR->scopebb()); | 75 LLValue* ptr = DtoGEPi(src,0,0,"tmp",gIR->scopebb()); |
89 llvm::Value* val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); | 76 LLValue* val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); |
90 ptr = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); | 77 ptr = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); |
91 new llvm::StoreInst(val, ptr, gIR->scopebb()); | 78 new llvm::StoreInst(val, ptr, gIR->scopebb()); |
92 | 79 |
93 ptr = DtoGEPi(src,0,1,"tmp",gIR->scopebb()); | 80 ptr = DtoGEPi(src,0,1,"tmp",gIR->scopebb()); |
94 val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); | 81 val = new llvm::LoadInst(ptr,"tmp",gIR->scopebb()); |
102 if (!arrty) | 89 if (!arrty) |
103 { | 90 { |
104 Logger::cout() << "invalid: " << *src << '\n'; | 91 Logger::cout() << "invalid: " << *src << '\n'; |
105 assert(0); | 92 assert(0); |
106 } | 93 } |
107 const llvm::Type* dstty = getPtrToType(arrty->getElementType()); | 94 const LLType* dstty = getPtrToType(arrty->getElementType()); |
108 | 95 |
109 llvm::Value* dstlen = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); | 96 LLValue* dstlen = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); |
110 llvm::Value* srclen = DtoConstSize_t(arrty->getNumElements()); | 97 LLValue* srclen = DtoConstSize_t(arrty->getNumElements()); |
111 new llvm::StoreInst(srclen, dstlen, gIR->scopebb()); | 98 new llvm::StoreInst(srclen, dstlen, gIR->scopebb()); |
112 | 99 |
113 llvm::Value* dstptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb()); | 100 LLValue* dstptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb()); |
114 llvm::Value* srcptr = new llvm::BitCastInst(src,dstty,"tmp",gIR->scopebb()); | 101 LLValue* srcptr = DtoBitCast(src, dstty); |
115 new llvm::StoreInst(srcptr, dstptr, gIR->scopebb()); | 102 new llvm::StoreInst(srcptr, dstptr, gIR->scopebb()); |
116 } | 103 } |
117 } | 104 } |
118 | 105 |
119 ////////////////////////////////////////////////////////////////////////////////////////// | 106 ////////////////////////////////////////////////////////////////////////////////////////// |
120 | 107 |
121 void DtoArrayInit(llvm::Value* l, llvm::Value* r) | 108 void DtoArrayInit(LLValue* l, LLValue* r) |
122 { | 109 { |
123 Logger::println("DtoArrayInit"); | 110 Logger::println("DtoArrayInit"); |
124 LOG_SCOPE; | 111 LOG_SCOPE; |
125 | 112 |
126 const llvm::PointerType* ptrty = isaPointer(l->getType()); | 113 const llvm::PointerType* ptrty = isaPointer(l->getType()); |
127 const llvm::Type* t = ptrty->getContainedType(0); | 114 const LLType* t = ptrty->getContainedType(0); |
128 const llvm::ArrayType* arrty = isaArray(t); | 115 const llvm::ArrayType* arrty = isaArray(t); |
129 if (arrty) | 116 if (arrty) |
130 { | 117 { |
131 llvm::Value* ptr = DtoGEPi(l,0,0,"tmp",gIR->scopebb()); | 118 LLValue* ptr = DtoGEPi(l,0,0,"tmp",gIR->scopebb()); |
132 llvm::Value* dim = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); | 119 LLValue* dim = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); |
133 DtoArrayInit(ptr, dim, r); | 120 DtoArrayInit(ptr, dim, r); |
134 } | 121 } |
135 else if (isaStruct(t)) | 122 else if (isaStruct(t)) |
136 { | 123 { |
137 llvm::Value* dim = DtoLoad(DtoGEPi(l, 0,0, "tmp")); | 124 LLValue* dim = DtoLoad(DtoGEPi(l, 0,0, "tmp")); |
138 llvm::Value* ptr = DtoLoad(DtoGEPi(l, 0,1, "tmp")); | 125 LLValue* ptr = DtoLoad(DtoGEPi(l, 0,1, "tmp")); |
139 DtoArrayInit(ptr, dim, r); | 126 DtoArrayInit(ptr, dim, r); |
140 } | 127 } |
141 else | 128 else |
142 assert(0); | 129 assert(0); |
143 } | 130 } |
144 | 131 |
145 ////////////////////////////////////////////////////////////////////////////////////////// | 132 ////////////////////////////////////////////////////////////////////////////////////////// |
146 | 133 |
147 typedef const llvm::Type* constLLVMTypeP; | 134 typedef const LLType* constLLVMTypeP; |
148 | 135 |
149 static size_t checkRectArrayInit(const llvm::Type* pt, constLLVMTypeP& finalty) | 136 static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty) |
150 { | 137 { |
151 if (const llvm::ArrayType* arrty = isaArray(pt)) { | 138 if (const llvm::ArrayType* arrty = isaArray(pt)) { |
152 size_t n = checkRectArrayInit(arrty->getElementType(), finalty); | 139 size_t n = checkRectArrayInit(arrty->getElementType(), finalty); |
153 size_t ne = arrty->getNumElements(); | 140 size_t ne = arrty->getNumElements(); |
154 if (n) return n * ne; | 141 if (n) return n * ne; |
156 } | 143 } |
157 finalty = pt; | 144 finalty = pt; |
158 return 0; | 145 return 0; |
159 } | 146 } |
160 | 147 |
161 void DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val) | 148 void DtoArrayInit(LLValue* ptr, LLValue* dim, LLValue* val) |
162 { | 149 { |
163 Logger::println("DtoArrayInit"); | 150 Logger::println("DtoArrayInit"); |
164 LOG_SCOPE; | 151 LOG_SCOPE; |
165 | 152 |
166 Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; | 153 Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; |
167 const llvm::Type* pt = ptr->getType()->getContainedType(0); | 154 const LLType* pt = ptr->getType()->getContainedType(0); |
168 const llvm::Type* t = val->getType(); | 155 const LLType* t = val->getType(); |
169 const llvm::Type* finalTy; | 156 const LLType* finalTy; |
170 size_t aggrsz = 0; | 157 size_t aggrsz = 0; |
171 if (size_t arrsz = checkRectArrayInit(pt, finalTy)) { | 158 if (size_t arrsz = checkRectArrayInit(pt, finalTy)) { |
172 assert(finalTy == t); | 159 assert(finalTy == t); |
173 llvm::Constant* c = isaConstant(dim); | 160 LLConstant* c = isaConstant(dim); |
174 assert(c); | 161 assert(c); |
175 dim = llvm::ConstantExpr::getMul(c, DtoConstSize_t(arrsz)); | 162 dim = llvm::ConstantExpr::getMul(c, DtoConstSize_t(arrsz)); |
176 ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(finalTy), "tmp"); | 163 ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(finalTy), "tmp"); |
177 } | 164 } |
178 else if (isaStruct(t)) { | 165 else if (isaStruct(t)) { |
179 aggrsz = getABITypeSize(t); | 166 aggrsz = getABITypeSize(t); |
180 llvm::Constant* c = isaConstant(val); | 167 LLConstant* c = isaConstant(val); |
181 if (c && c->isNullValue()) { | 168 if (c && c->isNullValue()) { |
182 llvm::Value* nbytes; | 169 LLValue* nbytes; |
183 if (aggrsz == 1) | 170 if (aggrsz == 1) |
184 nbytes = dim; | 171 nbytes = dim; |
185 else | 172 else |
186 nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp"); | 173 nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp"); |
187 DtoMemSetZero(ptr,nbytes); | 174 DtoMemSetZero(ptr,nbytes); |
195 assert(t == pt); | 182 assert(t == pt); |
196 } | 183 } |
197 | 184 |
198 Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; | 185 Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n'; |
199 | 186 |
200 std::vector<llvm::Value*> args; | 187 std::vector<LLValue*> args; |
201 args.push_back(ptr); | 188 args.push_back(ptr); |
202 args.push_back(dim); | 189 args.push_back(dim); |
203 args.push_back(val); | 190 args.push_back(val); |
204 | 191 |
205 const char* funcname = NULL; | 192 const char* funcname = NULL; |
209 args.push_back(DtoConstSize_t(aggrsz)); | 196 args.push_back(DtoConstSize_t(aggrsz)); |
210 } | 197 } |
211 else if (isaPointer(t)) { | 198 else if (isaPointer(t)) { |
212 funcname = "_d_array_init_pointer"; | 199 funcname = "_d_array_init_pointer"; |
213 | 200 |
214 const llvm::Type* dstty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); | 201 const LLType* dstty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); |
215 if (args[0]->getType() != dstty) | 202 if (args[0]->getType() != dstty) |
216 args[0] = new llvm::BitCastInst(args[0],dstty,"tmp",gIR->scopebb()); | 203 args[0] = DtoBitCast(args[0],dstty); |
217 | 204 |
218 const llvm::Type* valty = getPtrToType(llvm::Type::Int8Ty); | 205 const LLType* valty = getPtrToType(llvm::Type::Int8Ty); |
219 if (args[2]->getType() != valty) | 206 if (args[2]->getType() != valty) |
220 args[2] = new llvm::BitCastInst(args[2],valty,"tmp",gIR->scopebb()); | 207 args[2] = DtoBitCast(args[2],valty); |
221 } | 208 } |
222 else if (t == llvm::Type::Int1Ty) { | 209 else if (t == llvm::Type::Int1Ty) { |
223 funcname = "_d_array_init_i1"; | 210 funcname = "_d_array_init_i1"; |
224 } | 211 } |
225 else if (t == llvm::Type::Int8Ty) { | 212 else if (t == llvm::Type::Int8Ty) { |
252 call->setCallingConv(llvm::CallingConv::C); | 239 call->setCallingConv(llvm::CallingConv::C); |
253 } | 240 } |
254 | 241 |
255 ////////////////////////////////////////////////////////////////////////////////////////// | 242 ////////////////////////////////////////////////////////////////////////////////////////// |
256 | 243 |
257 void DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr) | 244 void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr) |
258 { | 245 { |
259 Logger::println("DtoSetArray"); | 246 Logger::println("DtoSetArray"); |
260 LOG_SCOPE; | 247 LOG_SCOPE; |
261 | 248 |
262 Logger::cout() << "arr = " << *arr << '\n'; | 249 Logger::cout() << "arr = " << *arr << '\n'; |
263 Logger::cout() << "dim = " << *dim << '\n'; | 250 Logger::cout() << "dim = " << *dim << '\n'; |
264 Logger::cout() << "ptr = " << *ptr << '\n'; | 251 Logger::cout() << "ptr = " << *ptr << '\n'; |
265 | 252 |
266 const llvm::StructType* st = isaStruct(arr->getType()->getContainedType(0)); | 253 const llvm::StructType* st = isaStruct(arr->getType()->getContainedType(0)); |
267 | 254 |
268 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 255 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
269 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 256 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
270 | 257 |
271 llvm::Value* arrdim = DtoGEP(arr,zero,zero,"tmp",gIR->scopebb()); | 258 LLValue* arrdim = DtoGEP(arr,zero,zero,"tmp",gIR->scopebb()); |
272 Logger::cout() << "arrdim = " << *arrdim << '\n'; | 259 Logger::cout() << "arrdim = " << *arrdim << '\n'; |
273 new llvm::StoreInst(dim, arrdim, gIR->scopebb()); | 260 new llvm::StoreInst(dim, arrdim, gIR->scopebb()); |
274 | 261 |
275 llvm::Value* arrptr = DtoGEP(arr,zero,one,"tmp",gIR->scopebb()); | 262 LLValue* arrptr = DtoGEP(arr,zero,one,"tmp",gIR->scopebb()); |
276 Logger::cout() << "arrptr = " << *arrptr << '\n'; | 263 Logger::cout() << "arrptr = " << *arrptr << '\n'; |
277 new llvm::StoreInst(ptr, arrptr, gIR->scopebb()); | 264 new llvm::StoreInst(ptr, arrptr, gIR->scopebb()); |
278 } | 265 } |
279 | 266 |
280 ////////////////////////////////////////////////////////////////////////////////////////// | 267 ////////////////////////////////////////////////////////////////////////////////////////// |
281 llvm::Constant* DtoConstArrayInitializer(ArrayInitializer* arrinit) | 268 LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) |
282 { | 269 { |
283 Logger::println("DtoConstArrayInitializer: %s | %s", arrinit->toChars(), arrinit->type->toChars()); | 270 Logger::println("DtoConstArrayInitializer: %s | %s", arrinit->toChars(), arrinit->type->toChars()); |
284 LOG_SCOPE; | 271 LOG_SCOPE; |
285 | 272 |
286 Type* arrinittype = DtoDType(arrinit->type); | 273 Type* arrinittype = DtoDType(arrinit->type); |
301 else | 288 else |
302 assert(0); | 289 assert(0); |
303 | 290 |
304 Logger::println("dim = %u", tdim); | 291 Logger::println("dim = %u", tdim); |
305 | 292 |
306 std::vector<llvm::Constant*> inits(tdim, NULL); | 293 std::vector<LLConstant*> inits(tdim, NULL); |
307 | 294 |
308 Type* arrnext = arrinittype->next; | 295 Type* arrnext = arrinittype->next; |
309 const llvm::Type* elemty = DtoType(arrinittype->next); | 296 const LLType* elemty = DtoType(arrinittype->next); |
310 | 297 |
311 assert(arrinit->index.dim == arrinit->value.dim); | 298 assert(arrinit->index.dim == arrinit->value.dim); |
312 for (unsigned i=0,j=0; i < tdim; ++i) | 299 for (unsigned i=0,j=0; i < tdim; ++i) |
313 { | 300 { |
314 Initializer* init = 0; | 301 Initializer* init = 0; |
317 if (j < arrinit->index.dim) | 304 if (j < arrinit->index.dim) |
318 idx = (Expression*)arrinit->index.data[j]; | 305 idx = (Expression*)arrinit->index.data[j]; |
319 else | 306 else |
320 idx = NULL; | 307 idx = NULL; |
321 | 308 |
322 llvm::Constant* v = NULL; | 309 LLConstant* v = NULL; |
323 | 310 |
324 if (idx) | 311 if (idx) |
325 { | 312 { |
326 Logger::println("%d has idx", i); | 313 Logger::println("%d has idx", i); |
327 // this is pretty weird :/ idx->type turned out NULL for the initializer: | 314 // this is pretty weird :/ idx->type turned out NULL for the initializer: |
329 // in std.c.linux.socket | 316 // in std.c.linux.socket |
330 if (idx->type) { | 317 if (idx->type) { |
331 Logger::println("has idx->type", i); | 318 Logger::println("has idx->type", i); |
332 //integer_t k = idx->toInteger(); | 319 //integer_t k = idx->toInteger(); |
333 //Logger::println("getting value for exp: %s | %s", idx->toChars(), arrnext->toChars()); | 320 //Logger::println("getting value for exp: %s | %s", idx->toChars(), arrnext->toChars()); |
334 llvm::Constant* cc = idx->toConstElem(gIR); | 321 LLConstant* cc = idx->toConstElem(gIR); |
335 Logger::println("value gotten"); | 322 Logger::println("value gotten"); |
336 assert(cc != NULL); | 323 assert(cc != NULL); |
337 llvm::ConstantInt* ci = llvm::dyn_cast<llvm::ConstantInt>(cc); | 324 llvm::ConstantInt* ci = llvm::dyn_cast<llvm::ConstantInt>(cc); |
338 assert(ci != NULL); | 325 assert(ci != NULL); |
339 uint64_t k = ci->getZExtValue(); | 326 uint64_t k = ci->getZExtValue(); |
363 Logger::cout() << "llval: " << *v << '\n'; | 350 Logger::cout() << "llval: " << *v << '\n'; |
364 } | 351 } |
365 | 352 |
366 Logger::println("building constant array"); | 353 Logger::println("building constant array"); |
367 const llvm::ArrayType* arrty = llvm::ArrayType::get(elemty,tdim); | 354 const llvm::ArrayType* arrty = llvm::ArrayType::get(elemty,tdim); |
368 llvm::Constant* constarr = llvm::ConstantArray::get(arrty, inits); | 355 LLConstant* constarr = llvm::ConstantArray::get(arrty, inits); |
369 | 356 |
370 if (arrinittype->ty == Tsarray) | 357 if (arrinittype->ty == Tsarray) |
371 return constarr; | 358 return constarr; |
372 else | 359 else |
373 assert(arrinittype->ty == Tarray); | 360 assert(arrinittype->ty == Tarray); |
374 | 361 |
375 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrty,true,llvm::GlobalValue::InternalLinkage,constarr,"constarray",gIR->module); | 362 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrty,true,llvm::GlobalValue::InternalLinkage,constarr,"constarray",gIR->module); |
376 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; | 363 LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; |
377 llvm::Constant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | 364 LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
378 return DtoConstSlice(DtoConstSize_t(tdim),gep); | 365 return DtoConstSlice(DtoConstSize_t(tdim),gep); |
379 } | 366 } |
380 | 367 |
381 ////////////////////////////////////////////////////////////////////////////////////////// | 368 ////////////////////////////////////////////////////////////////////////////////////////// |
382 static llvm::Value* get_slice_ptr(DSliceValue* e, llvm::Value*& sz) | 369 static LLValue* get_slice_ptr(DSliceValue* e, LLValue*& sz) |
383 { | 370 { |
384 const llvm::Type* t = e->ptr->getType()->getContainedType(0); | 371 const LLType* t = e->ptr->getType()->getContainedType(0); |
385 llvm::Value* ret = 0; | 372 LLValue* ret = 0; |
386 if (e->len != 0) { | 373 if (e->len != 0) { |
387 // this means it's a real slice | 374 // this means it's a real slice |
388 ret = e->ptr; | 375 ret = e->ptr; |
389 | 376 |
390 size_t elembsz = getABITypeSize(ret->getType()); | 377 size_t elembsz = getABITypeSize(ret->getType()); |
413 ret = new llvm::LoadInst(ret, "tmp", gIR->scopebb()); | 400 ret = new llvm::LoadInst(ret, "tmp", gIR->scopebb()); |
414 | 401 |
415 size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0)); | 402 size_t elembsz = getABITypeSize(ret->getType()->getContainedType(0)); |
416 llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false); | 403 llvm::ConstantInt* elemsz = llvm::ConstantInt::get(DtoSize_t(), elembsz, false); |
417 | 404 |
418 llvm::Value* len = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb()); | 405 LLValue* len = DtoGEPi(e->ptr, 0, 0, "tmp", gIR->scopebb()); |
419 len = new llvm::LoadInst(len, "tmp", gIR->scopebb()); | 406 len = new llvm::LoadInst(len, "tmp", gIR->scopebb()); |
420 sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb()); | 407 sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb()); |
421 } | 408 } |
422 else { | 409 else { |
423 assert(0); | 410 assert(0); |
426 } | 413 } |
427 | 414 |
428 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src) | 415 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src) |
429 { | 416 { |
430 Logger::println("ArrayCopySlices"); | 417 Logger::println("ArrayCopySlices"); |
431 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); | 418 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); |
432 | 419 |
433 llvm::Value* sz1; | 420 LLValue* sz1; |
434 llvm::Value* dstarr = new llvm::BitCastInst(get_slice_ptr(dst,sz1),arrty,"tmp",gIR->scopebb()); | 421 LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty); |
435 | 422 |
436 llvm::Value* sz2; | 423 LLValue* sz2; |
437 llvm::Value* srcarr = new llvm::BitCastInst(get_slice_ptr(src,sz2),arrty,"tmp",gIR->scopebb()); | 424 LLValue* srcarr = DtoBitCast(get_slice_ptr(src,sz2),arrty); |
438 | 425 |
439 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); | 426 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
440 std::vector<llvm::Value*> llargs; | 427 std::vector<LLValue*> llargs; |
441 llargs.resize(4); | 428 llargs.resize(4); |
442 llargs[0] = dstarr; | 429 llargs[0] = dstarr; |
443 llargs[1] = srcarr; | 430 llargs[1] = srcarr; |
444 llargs[2] = sz1; | 431 llargs[2] = sz1; |
445 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 432 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
448 } | 435 } |
449 | 436 |
450 void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src) | 437 void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src) |
451 { | 438 { |
452 Logger::println("ArrayCopyToSlice"); | 439 Logger::println("ArrayCopyToSlice"); |
453 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); | 440 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); |
454 | 441 |
455 llvm::Value* sz1; | 442 LLValue* sz1; |
456 llvm::Value* dstarr = new llvm::BitCastInst(get_slice_ptr(dst,sz1),arrty,"tmp",gIR->scopebb()); | 443 LLValue* dstarr = DtoBitCast(get_slice_ptr(dst,sz1),arrty); |
457 llvm::Value* srcarr = new llvm::BitCastInst(DtoArrayPtr(src),arrty,"tmp",gIR->scopebb()); | 444 LLValue* srcarr = DtoBitCast(DtoArrayPtr(src),arrty); |
458 | 445 |
459 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); | 446 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
460 std::vector<llvm::Value*> llargs; | 447 std::vector<LLValue*> llargs; |
461 llargs.resize(4); | 448 llargs.resize(4); |
462 llargs[0] = dstarr; | 449 llargs[0] = dstarr; |
463 llargs[1] = srcarr; | 450 llargs[1] = srcarr; |
464 llargs[2] = sz1; | 451 llargs[2] = sz1; |
465 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 452 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
466 | 453 |
467 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 454 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
468 } | 455 } |
469 | 456 |
470 ////////////////////////////////////////////////////////////////////////////////////////// | 457 ////////////////////////////////////////////////////////////////////////////////////////// |
471 void DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src) | 458 void DtoStaticArrayCopy(LLValue* dst, LLValue* src) |
472 { | 459 { |
473 Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n'; | 460 Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n'; |
474 assert(dst->getType() == src->getType()); | 461 assert(dst->getType() == src->getType()); |
475 size_t arrsz = getABITypeSize(dst->getType()->getContainedType(0)); | 462 size_t arrsz = getABITypeSize(dst->getType()->getContainedType(0)); |
476 llvm::Value* n = llvm::ConstantInt::get(DtoSize_t(), arrsz, false); | 463 LLValue* n = llvm::ConstantInt::get(DtoSize_t(), arrsz, false); |
477 | 464 |
478 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); | 465 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); |
479 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | 466 LLValue* dstarr = DtoBitCast(dst,arrty); |
480 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); | 467 LLValue* srcarr = DtoBitCast(src,arrty); |
481 | 468 |
482 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); | 469 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
483 std::vector<llvm::Value*> llargs; | 470 std::vector<LLValue*> llargs; |
484 llargs.resize(4); | 471 llargs.resize(4); |
485 llargs[0] = dstarr; | 472 llargs[0] = dstarr; |
486 llargs[1] = srcarr; | 473 llargs[1] = srcarr; |
487 llargs[2] = n; | 474 llargs[2] = n; |
488 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 475 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
489 | 476 |
490 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 477 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
491 } | 478 } |
492 | 479 |
493 ////////////////////////////////////////////////////////////////////////////////////////// | 480 ////////////////////////////////////////////////////////////////////////////////////////// |
494 llvm::Constant* DtoConstSlice(llvm::Constant* dim, llvm::Constant* ptr) | 481 LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) |
495 { | 482 { |
496 std::vector<const llvm::Type*> types; | 483 std::vector<const LLType*> types; |
497 types.push_back(dim->getType()); | 484 types.push_back(dim->getType()); |
498 types.push_back(ptr->getType()); | 485 types.push_back(ptr->getType()); |
499 const llvm::StructType* type = llvm::StructType::get(types); | 486 const llvm::StructType* type = llvm::StructType::get(types); |
500 std::vector<llvm::Constant*> values; | 487 std::vector<LLConstant*> values; |
501 values.push_back(dim); | 488 values.push_back(dim); |
502 values.push_back(ptr); | 489 values.push_back(ptr); |
503 return llvm::ConstantStruct::get(type,values); | 490 return llvm::ConstantStruct::get(type,values); |
504 } | 491 } |
505 | 492 |
510 LOG_SCOPE; | 497 LOG_SCOPE; |
511 | 498 |
512 bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit(); | 499 bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit(); |
513 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" ); | 500 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" ); |
514 | 501 |
515 llvm::SmallVector<llvm::Value*,2> args; | 502 LLSmallVector<LLValue*,2> args; |
516 args.push_back(DtoTypeInfoOf(arrayType)); | 503 args.push_back(DtoTypeInfoOf(arrayType)); |
517 assert(DtoType(dim->getType()) == DtoSize_t()); | 504 assert(DtoType(dim->getType()) == DtoSize_t()); |
518 args.push_back(dim->getRVal()); | 505 args.push_back(dim->getRVal()); |
519 | 506 |
520 llvm::Value* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem"); | 507 LLValue* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem"); |
521 const llvm::Type* dstType = DtoType(arrayType)->getContainedType(1); | 508 const LLType* dstType = DtoType(arrayType)->getContainedType(1); |
522 if (newptr->getType() != dstType) | 509 if (newptr->getType() != dstType) |
523 newptr = DtoBitCast(newptr, dstType, ".gc_mem"); | 510 newptr = DtoBitCast(newptr, dstType, ".gc_mem"); |
524 | 511 |
525 Logger::cout() << "final ptr = " << *newptr << '\n'; | 512 Logger::cout() << "final ptr = " << *newptr << '\n'; |
526 | 513 |
549 bool zeroInit = arrayType->toBasetype()->next->isZeroInit(); | 536 bool zeroInit = arrayType->toBasetype()->next->isZeroInit(); |
550 | 537 |
551 // call runtime | 538 // call runtime |
552 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" ); | 539 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" ); |
553 | 540 |
554 llvm::SmallVector<llvm::Value*,4> args; | 541 LLSmallVector<LLValue*,4> args; |
555 args.push_back(DtoTypeInfoOf(arrayType)); | 542 args.push_back(DtoTypeInfoOf(arrayType)); |
556 args.push_back(newdim->getRVal()); | 543 args.push_back(newdim->getRVal()); |
557 args.push_back(DtoArrayLen(array)); | 544 args.push_back(DtoArrayLen(array)); |
558 llvm::Value* arrPtr = DtoArrayPtr(array); | 545 LLValue* arrPtr = DtoArrayPtr(array); |
559 Logger::cout() << "arrPtr = " << *arrPtr << '\n'; | 546 Logger::cout() << "arrPtr = " << *arrPtr << '\n'; |
560 args.push_back(DtoBitCast(arrPtr, fn->getFunctionType()->getParamType(3), "tmp")); | 547 args.push_back(DtoBitCast(arrPtr, fn->getFunctionType()->getParamType(3), "tmp")); |
561 | 548 |
562 llvm::Value* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem"); | 549 LLValue* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem"); |
563 if (newptr->getType() != arrPtr->getType()) | 550 if (newptr->getType() != arrPtr->getType()) |
564 newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem"); | 551 newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem"); |
565 | 552 |
566 return new DSliceValue(arrayType, newdim->getRVal(), newptr); | 553 return new DSliceValue(arrayType, newdim->getRVal(), newptr); |
567 } | 554 } |
572 Logger::println("DtoCatAssignElement"); | 559 Logger::println("DtoCatAssignElement"); |
573 LOG_SCOPE; | 560 LOG_SCOPE; |
574 | 561 |
575 assert(array); | 562 assert(array); |
576 | 563 |
577 llvm::Value* idx = DtoArrayLen(array); | 564 LLValue* idx = DtoArrayLen(array); |
578 llvm::Value* one = DtoConstSize_t(1); | 565 LLValue* one = DtoConstSize_t(1); |
579 llvm::Value* len = gIR->ir->CreateAdd(idx,one,"tmp"); | 566 LLValue* len = gIR->ir->CreateAdd(idx,one,"tmp"); |
580 | 567 |
581 DValue* newdim = new DImValue(Type::tsize_t, len); | 568 DValue* newdim = new DImValue(Type::tsize_t, len); |
582 DSliceValue* slice = DtoResizeDynArray(array->getType(), array, newdim); | 569 DSliceValue* slice = DtoResizeDynArray(array->getType(), array, newdim); |
583 | 570 |
584 llvm::Value* ptr = slice->ptr; | 571 LLValue* ptr = slice->ptr; |
585 ptr = llvm::GetElementPtrInst::Create(ptr, idx, "tmp", gIR->scopebb()); | 572 ptr = llvm::GetElementPtrInst::Create(ptr, idx, "tmp", gIR->scopebb()); |
586 | 573 |
587 DValue* dptr = new DVarValue(exp->type, ptr, true); | 574 DValue* dptr = new DVarValue(exp->type, ptr, true); |
588 | 575 |
589 gIR->exps.push_back(IRExp(0,exp,dptr)); | 576 gIR->exps.push_back(IRExp(0,exp,dptr)); |
618 | 605 |
619 // advance ptr | 606 // advance ptr |
620 src1 = gIR->ir->CreateGEP(src1,len1,"tmp"); | 607 src1 = gIR->ir->CreateGEP(src1,len1,"tmp"); |
621 | 608 |
622 // memcpy | 609 // memcpy |
623 llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src2->getType()->getContainedType(0))); | 610 LLValue* elemSize = DtoConstSize_t(getABITypeSize(src2->getType()->getContainedType(0))); |
624 llvm::Value* bytelen = gIR->ir->CreateMul(len2, elemSize, "tmp"); | 611 LLValue* bytelen = gIR->ir->CreateMul(len2, elemSize, "tmp"); |
625 DtoMemCpy(src1,src2,bytelen); | 612 DtoMemCpy(src1,src2,bytelen); |
626 | 613 |
627 return slice; | 614 return slice; |
628 } | 615 } |
629 | 616 |
648 len2 = DtoArrayLen(e2); | 635 len2 = DtoArrayLen(e2); |
649 res = gIR->ir->CreateAdd(len1,len2,"tmp"); | 636 res = gIR->ir->CreateAdd(len1,len2,"tmp"); |
650 | 637 |
651 DValue* lenval = new DImValue(Type::tsize_t, res); | 638 DValue* lenval = new DImValue(Type::tsize_t, res); |
652 DSliceValue* slice = DtoNewDynArray(type, lenval, false); | 639 DSliceValue* slice = DtoNewDynArray(type, lenval, false); |
653 llvm::Value* mem = slice->ptr; | 640 LLValue* mem = slice->ptr; |
654 | 641 |
655 src1 = DtoArrayPtr(e1); | 642 src1 = DtoArrayPtr(e1); |
656 src2 = DtoArrayPtr(e2); | 643 src2 = DtoArrayPtr(e2); |
657 | 644 |
658 // first memcpy | 645 // first memcpy |
659 llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0))); | 646 LLValue* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0))); |
660 llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp"); | 647 LLValue* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp"); |
661 DtoMemCpy(mem,src1,bytelen); | 648 DtoMemCpy(mem,src1,bytelen); |
662 | 649 |
663 // second memcpy | 650 // second memcpy |
664 mem = gIR->ir->CreateGEP(mem,len1,"tmp"); | 651 mem = gIR->ir->CreateGEP(mem,len1,"tmp"); |
665 bytelen = gIR->ir->CreateMul(len2, elemSize, "tmp"); | 652 bytelen = gIR->ir->CreateMul(len2, elemSize, "tmp"); |
688 len1 = DtoArrayLen(e2); | 675 len1 = DtoArrayLen(e2); |
689 res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp"); | 676 res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp"); |
690 | 677 |
691 DValue* lenval = new DImValue(Type::tsize_t, res); | 678 DValue* lenval = new DImValue(Type::tsize_t, res); |
692 DSliceValue* slice = DtoNewDynArray(type, lenval, false); | 679 DSliceValue* slice = DtoNewDynArray(type, lenval, false); |
693 llvm::Value* mem = slice->ptr; | 680 LLValue* mem = slice->ptr; |
694 | 681 |
695 DVarValue* memval = new DVarValue(e1->getType(), mem, true); | 682 DVarValue* memval = new DVarValue(e1->getType(), mem, true); |
696 DtoAssign(memval, e1); | 683 DtoAssign(memval, e1); |
697 | 684 |
698 src1 = DtoArrayPtr(e2); | 685 src1 = DtoArrayPtr(e2); |
699 | 686 |
700 mem = gIR->ir->CreateGEP(mem,DtoConstSize_t(1),"tmp"); | 687 mem = gIR->ir->CreateGEP(mem,DtoConstSize_t(1),"tmp"); |
701 | 688 |
702 llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0))); | 689 LLValue* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0))); |
703 llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp"); | 690 LLValue* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp"); |
704 DtoMemCpy(mem,src1,bytelen); | 691 DtoMemCpy(mem,src1,bytelen); |
705 | 692 |
706 | 693 |
707 return slice; | 694 return slice; |
708 } | 695 } |
712 len1 = DtoArrayLen(e1); | 699 len1 = DtoArrayLen(e1); |
713 res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp"); | 700 res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp"); |
714 | 701 |
715 DValue* lenval = new DImValue(Type::tsize_t, res); | 702 DValue* lenval = new DImValue(Type::tsize_t, res); |
716 DSliceValue* slice = DtoNewDynArray(type, lenval, false); | 703 DSliceValue* slice = DtoNewDynArray(type, lenval, false); |
717 llvm::Value* mem = slice->ptr; | 704 LLValue* mem = slice->ptr; |
718 | 705 |
719 src1 = DtoArrayPtr(e1); | 706 src1 = DtoArrayPtr(e1); |
720 | 707 |
721 llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0))); | 708 LLValue* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0))); |
722 llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp"); | 709 LLValue* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp"); |
723 DtoMemCpy(mem,src1,bytelen); | 710 DtoMemCpy(mem,src1,bytelen); |
724 | 711 |
725 mem = gIR->ir->CreateGEP(mem,len1,"tmp"); | 712 mem = gIR->ir->CreateGEP(mem,len1,"tmp"); |
726 DVarValue* memval = new DVarValue(e2->getType(), mem, true); | 713 DVarValue* memval = new DVarValue(e2->getType(), mem, true); |
727 DtoAssign(memval, e2); | 714 DtoAssign(memval, e2); |
730 } | 717 } |
731 } | 718 } |
732 | 719 |
733 ////////////////////////////////////////////////////////////////////////////////////////// | 720 ////////////////////////////////////////////////////////////////////////////////////////// |
734 // helper for eq and cmp | 721 // helper for eq and cmp |
735 static llvm::Value* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti) | 722 static LLValue* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, bool useti) |
736 { | 723 { |
737 Logger::println("comparing arrays"); | 724 Logger::println("comparing arrays"); |
738 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, func); | 725 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, func); |
739 assert(fn); | 726 assert(fn); |
740 | 727 |
741 llvm::Value* lmem; | 728 LLValue* lmem; |
742 llvm::Value* rmem; | 729 LLValue* rmem; |
743 | 730 |
744 // cast static arrays to dynamic ones, this turns them into DSliceValues | 731 // cast static arrays to dynamic ones, this turns them into DSliceValues |
745 Logger::println("casting to dynamic arrays"); | 732 Logger::println("casting to dynamic arrays"); |
746 Type* l_ty = DtoDType(l->getType()); | 733 Type* l_ty = DtoDType(l->getType()); |
747 Type* r_ty = DtoDType(r->getType()); | 734 Type* r_ty = DtoDType(r->getType()); |
783 DtoSetArray(rmem, llvm::Constant::getNullValue(DtoSize_t()), llvm::Constant::getNullValue(DtoType(r->getType()->next->pointerTo()))); | 770 DtoSetArray(rmem, llvm::Constant::getNullValue(DtoSize_t()), llvm::Constant::getNullValue(DtoType(r->getType()->next->pointerTo()))); |
784 } | 771 } |
785 else | 772 else |
786 rmem = r->getRVal(); | 773 rmem = r->getRVal(); |
787 | 774 |
788 const llvm::Type* pt = fn->getFunctionType()->getParamType(0); | 775 const LLType* pt = fn->getFunctionType()->getParamType(0); |
789 | 776 |
790 std::vector<llvm::Value*> args; | 777 std::vector<LLValue*> args; |
791 Logger::cout() << "bitcasting to " << *pt << '\n'; | 778 Logger::cout() << "bitcasting to " << *pt << '\n'; |
792 Logger::cout() << *lmem << '\n'; | 779 Logger::cout() << *lmem << '\n'; |
793 Logger::cout() << *rmem << '\n'; | 780 Logger::cout() << *rmem << '\n'; |
794 args.push_back(DtoBitCast(lmem,pt)); | 781 args.push_back(DtoBitCast(lmem,pt)); |
795 args.push_back(DtoBitCast(rmem,pt)); | 782 args.push_back(DtoBitCast(rmem,pt)); |
796 | 783 |
797 // pass element typeinfo ? | 784 // pass element typeinfo ? |
798 if (useti) { | 785 if (useti) { |
799 TypeInfoDeclaration* ti = DtoDType(l->getType())->next->getTypeInfoDeclaration(); | 786 Type* t = DtoDType(l->getType())->next; |
800 DtoForceConstInitDsymbol(ti); | 787 LLValue* tival = DtoTypeInfoOf(t); |
801 Logger::cout() << "typeinfo decl: " << *ti->ir.getIrValue() << '\n'; | 788 // DtoTypeInfoOf only does declare, not enough in this case :/ |
789 DtoForceConstInitDsymbol(t->vtinfo); | |
790 Logger::cout() << "typeinfo decl: " << *tival << '\n'; | |
802 | 791 |
803 pt = fn->getFunctionType()->getParamType(2); | 792 pt = fn->getFunctionType()->getParamType(2); |
804 args.push_back(DtoBitCast(ti->ir.getIrValue(), pt)); | 793 args.push_back(DtoBitCast(tival, pt)); |
805 } | 794 } |
806 | 795 |
807 return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); | 796 return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp"); |
808 } | 797 } |
809 | 798 |
810 ////////////////////////////////////////////////////////////////////////////////////////// | 799 ////////////////////////////////////////////////////////////////////////////////////////// |
811 llvm::Value* DtoArrayEquals(TOK op, DValue* l, DValue* r) | 800 LLValue* DtoArrayEquals(TOK op, DValue* l, DValue* r) |
812 { | 801 { |
813 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_adEq"); | 802 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_adEq"); |
814 assert(fn); | 803 assert(fn); |
815 | 804 |
816 llvm::Value* res = DtoArrayEqCmp_impl("_adEq", l, r, true); | 805 LLValue* res = DtoArrayEqCmp_impl("_adEq", l, r, true); |
817 if (op == TOKnotequal) | 806 if (op == TOKnotequal) |
818 res = gIR->ir->CreateNot(res, "tmp"); | 807 res = gIR->ir->CreateNot(res, "tmp"); |
819 | 808 |
820 return res; | 809 return res; |
821 } | 810 } |
822 | 811 |
823 ////////////////////////////////////////////////////////////////////////////////////////// | 812 ////////////////////////////////////////////////////////////////////////////////////////// |
824 llvm::Value* DtoArrayCompare(TOK op, DValue* l, DValue* r) | 813 LLValue* DtoArrayCompare(TOK op, DValue* l, DValue* r) |
825 { | 814 { |
826 llvm::Value* res = 0; | 815 LLValue* res = 0; |
827 | 816 |
828 llvm::ICmpInst::Predicate cmpop; | 817 llvm::ICmpInst::Predicate cmpop; |
829 bool skip = false; | 818 bool skip = false; |
830 | 819 |
831 switch(op) | 820 switch(op) |
878 assert(res); | 867 assert(res); |
879 return res; | 868 return res; |
880 } | 869 } |
881 | 870 |
882 ////////////////////////////////////////////////////////////////////////////////////////// | 871 ////////////////////////////////////////////////////////////////////////////////////////// |
883 llvm::Value* DtoArrayCastLength(llvm::Value* len, const llvm::Type* elemty, const llvm::Type* newelemty) | 872 LLValue* DtoArrayCastLength(LLValue* len, const LLType* elemty, const LLType* newelemty) |
884 { | 873 { |
885 Logger::println("DtoArrayCastLength"); | 874 Logger::println("DtoArrayCastLength"); |
886 LOG_SCOPE; | 875 LOG_SCOPE; |
887 | 876 |
888 assert(len); | 877 assert(len); |
892 size_t esz = getABITypeSize(elemty); | 881 size_t esz = getABITypeSize(elemty); |
893 size_t nsz = getABITypeSize(newelemty); | 882 size_t nsz = getABITypeSize(newelemty); |
894 if (esz == nsz) | 883 if (esz == nsz) |
895 return len; | 884 return len; |
896 | 885 |
897 std::vector<llvm::Value*> args; | 886 std::vector<LLValue*> args; |
898 args.push_back(len); | 887 args.push_back(len); |
899 args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false)); | 888 args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false)); |
900 args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false)); | 889 args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false)); |
901 | 890 |
902 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len"); | 891 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len"); |
903 return llvm::CallInst::Create(fn, args.begin(), args.end(), "tmp", gIR->scopebb()); | 892 return llvm::CallInst::Create(fn, args.begin(), args.end(), "tmp", gIR->scopebb()); |
904 } | 893 } |
905 | 894 |
906 ////////////////////////////////////////////////////////////////////////////////////////// | 895 ////////////////////////////////////////////////////////////////////////////////////////// |
907 llvm::Value* DtoDynArrayIs(TOK op, llvm::Value* l, llvm::Value* r) | 896 LLValue* DtoDynArrayIs(TOK op, LLValue* l, LLValue* r) |
908 { | 897 { |
909 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; | 898 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; |
910 | 899 |
911 if (r == NULL) { | 900 if (r == NULL) { |
912 llvm::Value* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); | 901 LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); |
913 llvm::Value* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0); | 902 LLValue* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0); |
914 llvm::Value* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); | 903 LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); |
915 | 904 |
916 llvm::Value* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); | 905 LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); |
917 const llvm::PointerType* pty = isaPointer(lp->getType()); | 906 const llvm::PointerType* pty = isaPointer(lp->getType()); |
918 llvm::Value* rp = llvm::ConstantPointerNull::get(pty); | 907 LLValue* rp = llvm::ConstantPointerNull::get(pty); |
919 llvm::Value* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); | 908 LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); |
920 | 909 |
921 llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); | 910 LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp"); |
922 return b; | 911 return b; |
923 } | 912 } |
924 else { | 913 else { |
925 assert(l->getType() == r->getType()); | 914 assert(l->getType() == r->getType()); |
926 | 915 |
927 llvm::Value* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); | 916 LLValue* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); |
928 llvm::Value* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0, "tmp"),"tmp"); | 917 LLValue* rl = gIR->ir->CreateLoad(DtoGEPi(r, 0,0, "tmp"),"tmp"); |
929 llvm::Value* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); | 918 LLValue* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); |
930 | 919 |
931 llvm::Value* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); | 920 LLValue* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); |
932 llvm::Value* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1, "tmp"),"tmp"); | 921 LLValue* rp = gIR->ir->CreateLoad(DtoGEPi(r, 0,1, "tmp"),"tmp"); |
933 llvm::Value* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); | 922 LLValue* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); |
934 | 923 |
935 llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); | 924 LLValue* b = gIR->ir->CreateAnd(b1,b2,"tmp"); |
936 return b; | 925 return b; |
937 } | 926 } |
938 } | 927 } |
939 | 928 |
940 ////////////////////////////////////////////////////////////////////////////////////////// | 929 ////////////////////////////////////////////////////////////////////////////////////////// |
941 llvm::Constant* DtoConstStaticArray(const llvm::Type* t, llvm::Constant* c) | 930 LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c) |
942 { | 931 { |
943 const llvm::ArrayType* at = isaArray(t); | 932 const llvm::ArrayType* at = isaArray(t); |
944 assert(at); | 933 assert(at); |
945 | 934 |
946 if (isaArray(at->getElementType())) | 935 if (isaArray(at->getElementType())) |
948 c = DtoConstStaticArray(at->getElementType(), c); | 937 c = DtoConstStaticArray(at->getElementType(), c); |
949 } | 938 } |
950 else { | 939 else { |
951 assert(at->getElementType() == c->getType()); | 940 assert(at->getElementType() == c->getType()); |
952 } | 941 } |
953 std::vector<llvm::Constant*> initvals; | 942 std::vector<LLConstant*> initvals; |
954 initvals.resize(at->getNumElements(), c); | 943 initvals.resize(at->getNumElements(), c); |
955 return llvm::ConstantArray::get(at, initvals); | 944 return llvm::ConstantArray::get(at, initvals); |
956 } | 945 } |
957 | 946 |
958 ////////////////////////////////////////////////////////////////////////////////////////// | 947 ////////////////////////////////////////////////////////////////////////////////////////// |
959 llvm::Value* DtoArrayLen(DValue* v) | 948 LLValue* DtoArrayLen(DValue* v) |
960 { | 949 { |
961 Logger::println("DtoArrayLen"); | 950 Logger::println("DtoArrayLen"); |
962 LOG_SCOPE; | 951 LOG_SCOPE; |
963 | 952 |
964 Type* t = DtoDType(v->getType()); | 953 Type* t = DtoDType(v->getType()); |
975 } | 964 } |
976 return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp")); | 965 return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp")); |
977 } | 966 } |
978 else if (t->ty == Tsarray) { | 967 else if (t->ty == Tsarray) { |
979 assert(!v->isSlice()); | 968 assert(!v->isSlice()); |
980 llvm::Value* rv = v->getRVal(); | 969 LLValue* rv = v->getRVal(); |
981 Logger::cout() << "casting: " << *rv << '\n'; | 970 Logger::cout() << "casting: " << *rv << '\n'; |
982 const llvm::ArrayType* t = isaArray(rv->getType()->getContainedType(0)); | 971 const llvm::ArrayType* t = isaArray(rv->getType()->getContainedType(0)); |
983 return DtoConstSize_t(t->getNumElements()); | 972 return DtoConstSize_t(t->getNumElements()); |
984 } | 973 } |
985 assert(0); | 974 assert(0); |
986 return 0; | 975 return 0; |
987 } | 976 } |
988 | 977 |
989 ////////////////////////////////////////////////////////////////////////////////////////// | 978 ////////////////////////////////////////////////////////////////////////////////////////// |
990 llvm::Value* DtoArrayPtr(DValue* v) | 979 LLValue* DtoArrayPtr(DValue* v) |
991 { | 980 { |
992 Logger::println("DtoArrayPtr"); | 981 Logger::println("DtoArrayPtr"); |
993 LOG_SCOPE; | 982 LOG_SCOPE; |
994 | 983 |
995 Type* t = DtoDType(v->getType()); | 984 Type* t = DtoDType(v->getType()); |
996 if (t->ty == Tarray) { | 985 if (t->ty == Tarray) { |
997 if (DSliceValue* s = v->isSlice()) { | 986 if (DSliceValue* s = v->isSlice()) { |
998 if (s->len) return s->ptr; | 987 if (s->len) return s->ptr; |
999 const llvm::Type* t = s->ptr->getType()->getContainedType(0); | 988 const LLType* t = s->ptr->getType()->getContainedType(0); |
1000 Logger::cout() << "ptr of full slice: " << *s->ptr << '\n'; | 989 Logger::cout() << "ptr of full slice: " << *s->ptr << '\n'; |
1001 const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0)); | 990 const llvm::ArrayType* arrTy = isaArray(s->ptr->getType()->getContainedType(0)); |
1002 if (arrTy) | 991 if (arrTy) |
1003 return DtoGEPi(s->ptr, 0,0, "tmp"); | 992 return DtoGEPi(s->ptr, 0,0, "tmp"); |
1004 else | 993 else |
1017 DValue* DtoCastArray(DValue* u, Type* to) | 1006 DValue* DtoCastArray(DValue* u, Type* to) |
1018 { | 1007 { |
1019 Logger::println("DtoCastArray"); | 1008 Logger::println("DtoCastArray"); |
1020 LOG_SCOPE; | 1009 LOG_SCOPE; |
1021 | 1010 |
1022 const llvm::Type* tolltype = DtoType(to); | 1011 const LLType* tolltype = DtoType(to); |
1023 | 1012 |
1024 Type* totype = DtoDType(to); | 1013 Type* totype = DtoDType(to); |
1025 Type* fromtype = DtoDType(u->getType()); | 1014 Type* fromtype = DtoDType(u->getType()); |
1026 assert(fromtype->ty == Tarray || fromtype->ty == Tsarray); | 1015 assert(fromtype->ty == Tarray || fromtype->ty == Tsarray); |
1027 | 1016 |
1028 llvm::Value* rval; | 1017 LLValue* rval; |
1029 llvm::Value* rval2; | 1018 LLValue* rval2; |
1030 bool isslice = false; | 1019 bool isslice = false; |
1031 | 1020 |
1032 Logger::cout() << "from array or sarray" << '\n'; | 1021 Logger::cout() << "from array or sarray" << '\n'; |
1033 if (totype->ty == Tpointer) { | 1022 if (totype->ty == Tpointer) { |
1034 Logger::cout() << "to pointer" << '\n'; | 1023 Logger::cout() << "to pointer" << '\n'; |
1036 if (rval->getType() != tolltype) | 1025 if (rval->getType() != tolltype) |
1037 rval = gIR->ir->CreateBitCast(rval, tolltype, "tmp"); | 1026 rval = gIR->ir->CreateBitCast(rval, tolltype, "tmp"); |
1038 } | 1027 } |
1039 else if (totype->ty == Tarray) { | 1028 else if (totype->ty == Tarray) { |
1040 Logger::cout() << "to array" << '\n'; | 1029 Logger::cout() << "to array" << '\n'; |
1041 const llvm::Type* ptrty = DtoType(totype->next); | 1030 const LLType* ptrty = DtoType(totype->next); |
1042 if (ptrty == llvm::Type::VoidTy) | 1031 if (ptrty == llvm::Type::VoidTy) |
1043 ptrty = llvm::Type::Int8Ty; | 1032 ptrty = llvm::Type::Int8Ty; |
1044 ptrty = getPtrToType(ptrty); | 1033 ptrty = getPtrToType(ptrty); |
1045 | 1034 |
1046 const llvm::Type* ety = DtoType(fromtype->next); | 1035 const LLType* ety = DtoType(fromtype->next); |
1047 if (ety == llvm::Type::VoidTy) | 1036 if (ety == llvm::Type::VoidTy) |
1048 ety = llvm::Type::Int8Ty; | 1037 ety = llvm::Type::Int8Ty; |
1049 | 1038 |
1050 if (DSliceValue* usl = u->isSlice()) { | 1039 if (DSliceValue* usl = u->isSlice()) { |
1051 Logger::println("from slice"); | 1040 Logger::println("from slice"); |
1052 Logger::cout() << "from: " << *usl->ptr << " to: " << *ptrty << '\n'; | 1041 Logger::cout() << "from: " << *usl->ptr << " to: " << *ptrty << '\n'; |
1053 rval = new llvm::BitCastInst(usl->ptr, ptrty, "tmp", gIR->scopebb()); | 1042 rval = DtoBitCast(usl->ptr, ptrty); |
1054 if (fromtype->next->size() == totype->next->size()) | 1043 if (fromtype->next->size() == totype->next->size()) |
1055 rval2 = DtoArrayLen(usl); | 1044 rval2 = DtoArrayLen(usl); |
1056 else | 1045 else |
1057 rval2 = DtoArrayCastLength(DtoArrayLen(usl), ety, ptrty->getContainedType(0)); | 1046 rval2 = DtoArrayCastLength(DtoArrayLen(usl), ety, ptrty->getContainedType(0)); |
1058 } | 1047 } |
1059 else { | 1048 else { |
1060 llvm::Value* uval = u->getRVal(); | 1049 LLValue* uval = u->getRVal(); |
1061 if (fromtype->ty == Tsarray) { | 1050 if (fromtype->ty == Tsarray) { |
1062 Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; | 1051 Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; |
1063 assert(isaPointer(uval->getType())); | 1052 assert(isaPointer(uval->getType())); |
1064 const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); | 1053 const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0)); |
1065 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); | 1054 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); |
1066 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); | 1055 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); |
1067 rval = new llvm::BitCastInst(uval, ptrty, "tmp", gIR->scopebb()); | 1056 rval = DtoBitCast(uval, ptrty); |
1068 } | 1057 } |
1069 else { | 1058 else { |
1070 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1059 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1071 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1060 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
1072 rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb()); | 1061 rval2 = DtoGEP(uval,zero,zero,"tmp",gIR->scopebb()); |
1073 rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb()); | 1062 rval2 = new llvm::LoadInst(rval2, "tmp", gIR->scopebb()); |
1074 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); | 1063 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); |
1075 | 1064 |
1076 rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb()); | 1065 rval = DtoGEP(uval,zero,one,"tmp",gIR->scopebb()); |
1077 rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb()); | 1066 rval = new llvm::LoadInst(rval, "tmp", gIR->scopebb()); |
1078 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n'; | 1067 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n'; |
1079 rval = new llvm::BitCastInst(rval, ptrty, "tmp", gIR->scopebb()); | 1068 rval = DtoBitCast(rval, ptrty); |
1080 } | 1069 } |
1081 } | 1070 } |
1082 isslice = true; | 1071 isslice = true; |
1083 } | 1072 } |
1084 else if (totype->ty == Tsarray) { | 1073 else if (totype->ty == Tsarray) { |