Mercurial > projects > ldc
comparison gen/structs.cpp @ 173:db9890b3fb64 trunk
[svn r189] moving IR data back into DMD frontend nodes
author | ChristianK |
---|---|
date | Tue, 06 May 2008 07:56:03 +0200 |
parents | 95f07e3f8bb9 |
children | 9d44ec83acd1 |
comparison
equal
deleted
inserted
replaced
172:68a7dd38c03c | 173:db9890b3fb64 |
---|---|
80 Logger::println("DtoConstStructInitializer: %s", si->toChars()); | 80 Logger::println("DtoConstStructInitializer: %s", si->toChars()); |
81 LOG_SCOPE; | 81 LOG_SCOPE; |
82 | 82 |
83 TypeStruct* ts = (TypeStruct*)si->ad->type; | 83 TypeStruct* ts = (TypeStruct*)si->ad->type; |
84 | 84 |
85 const llvm::StructType* structtype = isaStruct(gIR->irType[ts].type->get()); | 85 const llvm::StructType* structtype = isaStruct(ts->ir.type->get()); |
86 Logger::cout() << "llvm struct type: " << *structtype << '\n'; | 86 Logger::cout() << "llvm struct type: " << *structtype << '\n'; |
87 | 87 |
88 assert(si->value.dim == si->vars.dim); | 88 assert(si->value.dim == si->vars.dim); |
89 | 89 |
90 std::vector<DUnionIdx> inits; | 90 std::vector<DUnionIdx> inits; |
93 Initializer* ini = (Initializer*)si->value.data[i]; | 93 Initializer* ini = (Initializer*)si->value.data[i]; |
94 assert(ini); | 94 assert(ini); |
95 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; | 95 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; |
96 assert(vd); | 96 assert(vd); |
97 llvm::Constant* v = DtoConstInitializer(vd->type, ini); | 97 llvm::Constant* v = DtoConstInitializer(vd->type, ini); |
98 inits.push_back(DUnionIdx(gIR->irDsymbol[vd].irField->index, gIR->irDsymbol[vd].irField->indexOffset, v)); | 98 inits.push_back(DUnionIdx(vd->ir.irField->index, vd->ir.irField->indexOffset, v)); |
99 } | 99 } |
100 | 100 |
101 DtoConstInitStruct((StructDeclaration*)si->ad); | 101 DtoConstInitStruct((StructDeclaration*)si->ad); |
102 return gIR->irDsymbol[si->ad].irStruct->dunion->getConst(inits); | 102 return si->ad->ir.irStruct->dunion->getConst(inits); |
103 } | 103 } |
104 | 104 |
105 ////////////////////////////////////////////////////////////////////////////////////////// | 105 ////////////////////////////////////////////////////////////////////////////////////////// |
106 | 106 |
107 llvm::Value* DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs) | 107 llvm::Value* DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs) |
113 idxs.push_back(0); | 113 idxs.push_back(0); |
114 | 114 |
115 const llvm::Type* llt = getPtrToType(DtoType(t)); | 115 const llvm::Type* llt = getPtrToType(DtoType(t)); |
116 const llvm::Type* st = getPtrToType(DtoType(sd->type)); | 116 const llvm::Type* st = getPtrToType(DtoType(sd->type)); |
117 if (ptr->getType() != st) { | 117 if (ptr->getType() != st) { |
118 assert(gIR->irDsymbol[sd].irStruct->hasUnions); | 118 assert(sd->ir.irStruct->hasUnions); |
119 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); | 119 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); |
120 } | 120 } |
121 | 121 |
122 for (unsigned i=0; i<sd->fields.dim; ++i) { | 122 for (unsigned i=0; i<sd->fields.dim; ++i) { |
123 VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i]; | 123 VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i]; |
124 Type* vdtype = DtoDType(vd->type); | 124 Type* vdtype = DtoDType(vd->type); |
125 //Logger::println("found %u type %s", vd->offset, vdtype->toChars()); | 125 //Logger::println("found %u type %s", vd->offset, vdtype->toChars()); |
126 assert(gIR->irDsymbol[vd].irField->index >= 0); | 126 assert(vd->ir.irField->index >= 0); |
127 if (os == vd->offset && vdtype == t) { | 127 if (os == vd->offset && vdtype == t) { |
128 idxs.push_back(gIR->irDsymbol[vd].irField->index); | 128 idxs.push_back(vd->ir.irField->index); |
129 ptr = DtoGEP(ptr, idxs, "tmp"); | 129 ptr = DtoGEP(ptr, idxs, "tmp"); |
130 if (ptr->getType() != llt) | 130 if (ptr->getType() != llt) |
131 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); | 131 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
132 if (gIR->irDsymbol[vd].irField->indexOffset) | 132 if (vd->ir.irField->indexOffset) |
133 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(gIR->irDsymbol[vd].irField->indexOffset), "tmp", gIR->scopebb()); | 133 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); |
134 return ptr; | 134 return ptr; |
135 } | 135 } |
136 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { | 136 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { |
137 TypeStruct* ts = (TypeStruct*)vdtype; | 137 TypeStruct* ts = (TypeStruct*)vdtype; |
138 StructDeclaration* ssd = ts->sym; | 138 StructDeclaration* ssd = ts->sym; |
139 idxs.push_back(gIR->irDsymbol[vd].irField->index); | 139 idxs.push_back(vd->ir.irField->index); |
140 if (gIR->irDsymbol[vd].irField->indexOffset) { | 140 if (vd->ir.irField->indexOffset) { |
141 Logger::println("has union field offset"); | 141 Logger::println("has union field offset"); |
142 ptr = DtoGEP(ptr, idxs, "tmp"); | 142 ptr = DtoGEP(ptr, idxs, "tmp"); |
143 if (ptr->getType() != llt) | 143 if (ptr->getType() != llt) |
144 ptr = DtoBitCast(ptr, llt); | 144 ptr = DtoBitCast(ptr, llt); |
145 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(gIR->irDsymbol[vd].irField->indexOffset), "tmp", gIR->scopebb()); | 145 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); |
146 std::vector<unsigned> tmp; | 146 std::vector<unsigned> tmp; |
147 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | 147 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
148 } | 148 } |
149 else { | 149 else { |
150 const llvm::Type* sty = getPtrToType(DtoType(vd->type)); | 150 const llvm::Type* sty = getPtrToType(DtoType(vd->type)); |
168 | 168 |
169 ////////////////////////////////////////////////////////////////////////////////////////// | 169 ////////////////////////////////////////////////////////////////////////////////////////// |
170 | 170 |
171 void DtoResolveStruct(StructDeclaration* sd) | 171 void DtoResolveStruct(StructDeclaration* sd) |
172 { | 172 { |
173 if (gIR->irDsymbol[sd].resolved) return; | 173 if (sd->ir.resolved) return; |
174 gIR->irDsymbol[sd].resolved = true; | 174 sd->ir.resolved = true; |
175 | 175 |
176 Logger::println("DtoResolveStruct(%s): %s", sd->toChars(), sd->loc.toChars()); | 176 Logger::println("DtoResolveStruct(%s): %s", sd->toChars(), sd->loc.toChars()); |
177 LOG_SCOPE; | 177 LOG_SCOPE; |
178 | 178 |
179 if (sd->prot() == PROTprivate && sd->getModule() != gIR->dmodule) | 179 if (sd->prot() == PROTprivate && sd->getModule() != gIR->dmodule) |
180 Logger::println("using a private struct from outside its module"); | 180 Logger::println("using a private struct from outside its module"); |
181 | 181 |
182 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); | 182 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); |
183 | 183 |
184 IrStruct* irstruct = new IrStruct(ts); | 184 IrStruct* irstruct = new IrStruct(ts); |
185 gIR->irDsymbol[sd].irStruct = irstruct; | 185 sd->ir.irStruct = irstruct; |
186 gIR->structs.push_back(irstruct); | 186 gIR->structs.push_back(irstruct); |
187 | 187 |
188 // fields | 188 // fields |
189 Array* arr = &sd->fields; | 189 Array* arr = &sd->fields; |
190 for (int k=0; k < arr->dim; k++) { | 190 for (int k=0; k < arr->dim; k++) { |
244 lastoffset = i->first; | 244 lastoffset = i->first; |
245 assert(lastoffset == 0); | 245 assert(lastoffset == 0); |
246 fieldtype = i->second.type; | 246 fieldtype = i->second.type; |
247 fieldinit = i->second.var; | 247 fieldinit = i->second.var; |
248 prevsize = getABITypeSize(fieldtype); | 248 prevsize = getABITypeSize(fieldtype); |
249 gIR->irDsymbol[i->second.var].irField->index = idx; | 249 i->second.var->ir.irField->index = idx; |
250 } | 250 } |
251 // colliding offset? | 251 // colliding offset? |
252 else if (lastoffset == i->first) { | 252 else if (lastoffset == i->first) { |
253 size_t s = getABITypeSize(i->second.type); | 253 size_t s = getABITypeSize(i->second.type); |
254 if (s > prevsize) { | 254 if (s > prevsize) { |
255 fieldpad += s - prevsize; | 255 fieldpad += s - prevsize; |
256 prevsize = s; | 256 prevsize = s; |
257 } | 257 } |
258 gIR->irDsymbol[sd].irStruct->hasUnions = true; | 258 sd->ir.irStruct->hasUnions = true; |
259 gIR->irDsymbol[i->second.var].irField->index = idx; | 259 i->second.var->ir.irField->index = idx; |
260 } | 260 } |
261 // intersecting offset? | 261 // intersecting offset? |
262 else if (i->first < (lastoffset + prevsize)) { | 262 else if (i->first < (lastoffset + prevsize)) { |
263 size_t s = getABITypeSize(i->second.type); | 263 size_t s = getABITypeSize(i->second.type); |
264 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size | 264 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size |
265 gIR->irDsymbol[sd].irStruct->hasUnions = true; | 265 sd->ir.irStruct->hasUnions = true; |
266 gIR->irDsymbol[i->second.var].irField->index = idx; | 266 i->second.var->ir.irField->index = idx; |
267 gIR->irDsymbol[i->second.var].irField->indexOffset = (i->first - lastoffset) / s; | 267 i->second.var->ir.irField->indexOffset = (i->first - lastoffset) / s; |
268 } | 268 } |
269 // fresh offset | 269 // fresh offset |
270 else { | 270 else { |
271 // commit the field | 271 // commit the field |
272 fieldtypes.push_back(fieldtype); | 272 fieldtypes.push_back(fieldtype); |
282 // start new | 282 // start new |
283 lastoffset = i->first; | 283 lastoffset = i->first; |
284 fieldtype = i->second.type; | 284 fieldtype = i->second.type; |
285 fieldinit = i->second.var; | 285 fieldinit = i->second.var; |
286 prevsize = getABITypeSize(fieldtype); | 286 prevsize = getABITypeSize(fieldtype); |
287 gIR->irDsymbol[i->second.var].irField->index = idx; | 287 i->second.var->ir.irField->index = idx; |
288 fieldpad = 0; | 288 fieldpad = 0; |
289 } | 289 } |
290 } | 290 } |
291 fieldtypes.push_back(fieldtype); | 291 fieldtypes.push_back(fieldtype); |
292 irstruct->defaultFields.push_back(fieldinit); | 292 irstruct->defaultFields.push_back(fieldinit); |
305 llvm::PATypeHolder& pa = irstruct->recty; | 305 llvm::PATypeHolder& pa = irstruct->recty; |
306 llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(structtype); | 306 llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(structtype); |
307 structtype = isaStruct(pa.get()); | 307 structtype = isaStruct(pa.get()); |
308 } | 308 } |
309 | 309 |
310 assert(gIR->irType[ts].type == 0); | 310 assert(ts->ir.type == 0); |
311 gIR->irType[ts].type = new llvm::PATypeHolder(structtype); | 311 ts->ir.type = new llvm::PATypeHolder(structtype); |
312 | 312 |
313 if (sd->parent->isModule()) { | 313 if (sd->parent->isModule()) { |
314 gIR->module->addTypeName(sd->mangle(),structtype); | 314 gIR->module->addTypeName(sd->mangle(),structtype); |
315 } | 315 } |
316 | 316 |
321 | 321 |
322 ////////////////////////////////////////////////////////////////////////////////////////// | 322 ////////////////////////////////////////////////////////////////////////////////////////// |
323 | 323 |
324 void DtoDeclareStruct(StructDeclaration* sd) | 324 void DtoDeclareStruct(StructDeclaration* sd) |
325 { | 325 { |
326 if (gIR->irDsymbol[sd].declared) return; | 326 if (sd->ir.declared) return; |
327 gIR->irDsymbol[sd].declared = true; | 327 sd->ir.declared = true; |
328 | 328 |
329 Logger::println("DtoDeclareStruct(%s): %s", sd->toChars(), sd->loc.toChars()); | 329 Logger::println("DtoDeclareStruct(%s): %s", sd->toChars(), sd->loc.toChars()); |
330 LOG_SCOPE; | 330 LOG_SCOPE; |
331 | 331 |
332 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); | 332 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); |
334 std::string initname("_D"); | 334 std::string initname("_D"); |
335 initname.append(sd->mangle()); | 335 initname.append(sd->mangle()); |
336 initname.append("6__initZ"); | 336 initname.append("6__initZ"); |
337 | 337 |
338 llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd); | 338 llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd); |
339 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(gIR->irType[ts].type->get(), true, _linkage, NULL, initname, gIR->module); | 339 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->ir.type->get(), true, _linkage, NULL, initname, gIR->module); |
340 gIR->irDsymbol[sd].irStruct->init = initvar; | 340 sd->ir.irStruct->init = initvar; |
341 | 341 |
342 gIR->constInitList.push_back(sd); | 342 gIR->constInitList.push_back(sd); |
343 if (DtoIsTemplateInstance(sd) || sd->getModule() == gIR->dmodule) | 343 if (DtoIsTemplateInstance(sd) || sd->getModule() == gIR->dmodule) |
344 gIR->defineList.push_back(sd); | 344 gIR->defineList.push_back(sd); |
345 } | 345 } |
346 | 346 |
347 ////////////////////////////////////////////////////////////////////////////////////////// | 347 ////////////////////////////////////////////////////////////////////////////////////////// |
348 | 348 |
349 void DtoConstInitStruct(StructDeclaration* sd) | 349 void DtoConstInitStruct(StructDeclaration* sd) |
350 { | 350 { |
351 if (gIR->irDsymbol[sd].initialized) return; | 351 if (sd->ir.initialized) return; |
352 gIR->irDsymbol[sd].initialized = true; | 352 sd->ir.initialized = true; |
353 | 353 |
354 Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars()); | 354 Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars()); |
355 LOG_SCOPE; | 355 LOG_SCOPE; |
356 | 356 |
357 IrStruct* irstruct = gIR->irDsymbol[sd].irStruct; | 357 IrStruct* irstruct = sd->ir.irStruct; |
358 gIR->structs.push_back(irstruct); | 358 gIR->structs.push_back(irstruct); |
359 | 359 |
360 // make sure each offset knows its default initializer | 360 // make sure each offset knows its default initializer |
361 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) | 361 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) |
362 { | 362 { |
363 IrStruct::Offset* so = &i->second; | 363 IrStruct::Offset* so = &i->second; |
364 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); | 364 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); |
365 so->init = finit; | 365 so->init = finit; |
366 gIR->irDsymbol[so->var].irField->constInit = finit; | 366 so->var->ir.irField->constInit = finit; |
367 } | 367 } |
368 | 368 |
369 const llvm::StructType* structtype = isaStruct(gIR->irType[sd->type].type->get()); | 369 const llvm::StructType* structtype = isaStruct(sd->type->ir.type->get()); |
370 | 370 |
371 // go through the field inits and build the default initializer | 371 // go through the field inits and build the default initializer |
372 std::vector<llvm::Constant*> fieldinits_ll; | 372 std::vector<llvm::Constant*> fieldinits_ll; |
373 size_t nfi = irstruct->defaultFields.size(); | 373 size_t nfi = irstruct->defaultFields.size(); |
374 for (size_t i=0; i<nfi; ++i) { | 374 for (size_t i=0; i<nfi; ++i) { |
375 llvm::Constant* c; | 375 llvm::Constant* c; |
376 if (irstruct->defaultFields[i] != NULL) { | 376 if (irstruct->defaultFields[i] != NULL) { |
377 c = gIR->irDsymbol[irstruct->defaultFields[i]].irField->constInit; | 377 c = irstruct->defaultFields[i]->ir.irField->constInit; |
378 assert(c); | 378 assert(c); |
379 } | 379 } |
380 else { | 380 else { |
381 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i)); | 381 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i)); |
382 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); | 382 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); |
384 } | 384 } |
385 fieldinits_ll.push_back(c); | 385 fieldinits_ll.push_back(c); |
386 } | 386 } |
387 | 387 |
388 // generate the union mapper | 388 // generate the union mapper |
389 gIR->irDsymbol[sd].irStruct->dunion = new DUnion; // uses gIR->topstruct() | 389 sd->ir.irStruct->dunion = new DUnion; // uses gIR->topstruct() |
390 | 390 |
391 // always generate the constant initalizer | 391 // always generate the constant initalizer |
392 if (!sd->zeroInit) { | 392 if (!sd->zeroInit) { |
393 Logger::println("Not zero initialized"); | 393 Logger::println("Not zero initialized"); |
394 //assert(tk == gIR->gIR->topstruct()().size()); | 394 //assert(tk == gIR->gIR->topstruct()().size()); |
400 Logger::cout() << "Value:" << '\n'; | 400 Logger::cout() << "Value:" << '\n'; |
401 Logger::cout() << *fieldinits_ll[k] << '\n'; | 401 Logger::cout() << *fieldinits_ll[k] << '\n'; |
402 } | 402 } |
403 Logger::cout() << "Initializer printed" << '\n'; | 403 Logger::cout() << "Initializer printed" << '\n'; |
404 #endif | 404 #endif |
405 gIR->irDsymbol[sd].irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll); | 405 sd->ir.irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll); |
406 } | 406 } |
407 else { | 407 else { |
408 Logger::println("Zero initialized"); | 408 Logger::println("Zero initialized"); |
409 gIR->irDsymbol[sd].irStruct->constInit = llvm::ConstantAggregateZero::get(structtype); | 409 sd->ir.irStruct->constInit = llvm::ConstantAggregateZero::get(structtype); |
410 } | 410 } |
411 | 411 |
412 gIR->structs.pop_back(); | 412 gIR->structs.pop_back(); |
413 | 413 |
414 // emit typeinfo | 414 // emit typeinfo |
418 | 418 |
419 ////////////////////////////////////////////////////////////////////////////////////////// | 419 ////////////////////////////////////////////////////////////////////////////////////////// |
420 | 420 |
421 void DtoDefineStruct(StructDeclaration* sd) | 421 void DtoDefineStruct(StructDeclaration* sd) |
422 { | 422 { |
423 if (gIR->irDsymbol[sd].defined) return; | 423 if (sd->ir.defined) return; |
424 gIR->irDsymbol[sd].defined = true; | 424 sd->ir.defined = true; |
425 | 425 |
426 Logger::println("DtoDefineStruct(%s): %s", sd->toChars(), sd->loc.toChars()); | 426 Logger::println("DtoDefineStruct(%s): %s", sd->toChars(), sd->loc.toChars()); |
427 LOG_SCOPE; | 427 LOG_SCOPE; |
428 | 428 |
429 assert(sd->type->ty == Tstruct); | 429 assert(sd->type->ty == Tstruct); |
430 TypeStruct* ts = (TypeStruct*)sd->type; | 430 TypeStruct* ts = (TypeStruct*)sd->type; |
431 gIR->irDsymbol[sd].irStruct->init->setInitializer(gIR->irDsymbol[sd].irStruct->constInit); | 431 sd->ir.irStruct->init->setInitializer(sd->ir.irStruct->constInit); |
432 | 432 |
433 gIR->irDsymbol[sd].DModule = gIR->dmodule; | 433 sd->ir.DModule = gIR->dmodule; |
434 } | 434 } |
435 | 435 |
436 ////////////////////////////////////////////////////////////////////////////////////////// | 436 ////////////////////////////////////////////////////////////////////////////////////////// |
437 //////////////////////////// D UNION HELPER CLASS //////////////////////////////////// | 437 //////////////////////////// D UNION HELPER CLASS //////////////////////////////////// |
438 ////////////////////////////////////////////////////////////////////////////////////////// | 438 ////////////////////////////////////////////////////////////////////////////////////////// |