Mercurial > projects > ldc
comparison gen/structs.cpp @ 156:ccd07d9f2ce9 trunk
[svn r172] moving all IR state previously stored in Dsymbol into IrDsymbol and a Dsymbol->IrDsymbol map
author | ChristianK |
---|---|
date | Thu, 01 May 2008 13:05:53 +0200 |
parents | 4c577c2b7229 |
children | 5c17f81fc1c1 |
comparison
equal
deleted
inserted
replaced
155:7f92f477ff53 | 156:ccd07d9f2ce9 |
---|---|
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(vd->irField->index, vd->irField->indexOffset, v)); | 98 inits.push_back(DUnionIdx(gIR->irDsymbol[vd].irField->index, gIR->irDsymbol[vd].irField->indexOffset, v)); |
99 } | 99 } |
100 | 100 |
101 DtoConstInitStruct((StructDeclaration*)si->ad); | 101 DtoConstInitStruct((StructDeclaration*)si->ad); |
102 return si->ad->irStruct->dunion->getConst(inits); | 102 return gIR->irDsymbol[si->ad].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(sd->irStruct->hasUnions); | 118 assert(gIR->irDsymbol[sd].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(vd->irField->index >= 0); | 126 assert(gIR->irDsymbol[vd].irField->index >= 0); |
127 if (os == vd->offset && vdtype == t) { | 127 if (os == vd->offset && vdtype == t) { |
128 idxs.push_back(vd->irField->index); | 128 idxs.push_back(gIR->irDsymbol[vd].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 (vd->irField->indexOffset) | 132 if (gIR->irDsymbol[vd].irField->indexOffset) |
133 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); | 133 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(gIR->irDsymbol[vd].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(vd->irField->index); | 139 idxs.push_back(gIR->irDsymbol[vd].irField->index); |
140 if (vd->irField->indexOffset) { | 140 if (gIR->irDsymbol[vd].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(vd->irField->indexOffset), "tmp", gIR->scopebb()); | 145 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(gIR->irDsymbol[vd].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 (sd->llvmResolved) return; | 173 if (gIR->irDsymbol[sd].resolved) return; |
174 sd->llvmResolved = true; | 174 gIR->irDsymbol[sd].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 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); | 179 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); |
180 | 180 |
181 IrStruct* irstruct = new IrStruct(ts); | 181 IrStruct* irstruct = new IrStruct(ts); |
182 sd->irStruct = irstruct; | 182 gIR->irDsymbol[sd].irStruct = irstruct; |
183 gIR->structs.push_back(irstruct); | 183 gIR->structs.push_back(irstruct); |
184 | 184 |
185 // fields | 185 // fields |
186 Array* arr = &sd->fields; | 186 Array* arr = &sd->fields; |
187 for (int k=0; k < arr->dim; k++) { | 187 for (int k=0; k < arr->dim; k++) { |
241 lastoffset = i->first; | 241 lastoffset = i->first; |
242 assert(lastoffset == 0); | 242 assert(lastoffset == 0); |
243 fieldtype = i->second.type; | 243 fieldtype = i->second.type; |
244 fieldinit = i->second.var; | 244 fieldinit = i->second.var; |
245 prevsize = getABITypeSize(fieldtype); | 245 prevsize = getABITypeSize(fieldtype); |
246 i->second.var->irField->index = idx; | 246 gIR->irDsymbol[i->second.var].irField->index = idx; |
247 } | 247 } |
248 // colliding offset? | 248 // colliding offset? |
249 else if (lastoffset == i->first) { | 249 else if (lastoffset == i->first) { |
250 size_t s = getABITypeSize(i->second.type); | 250 size_t s = getABITypeSize(i->second.type); |
251 if (s > prevsize) { | 251 if (s > prevsize) { |
252 fieldpad += s - prevsize; | 252 fieldpad += s - prevsize; |
253 prevsize = s; | 253 prevsize = s; |
254 } | 254 } |
255 sd->irStruct->hasUnions = true; | 255 gIR->irDsymbol[sd].irStruct->hasUnions = true; |
256 i->second.var->irField->index = idx; | 256 gIR->irDsymbol[i->second.var].irField->index = idx; |
257 } | 257 } |
258 // intersecting offset? | 258 // intersecting offset? |
259 else if (i->first < (lastoffset + prevsize)) { | 259 else if (i->first < (lastoffset + prevsize)) { |
260 size_t s = getABITypeSize(i->second.type); | 260 size_t s = getABITypeSize(i->second.type); |
261 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size | 261 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size |
262 sd->irStruct->hasUnions = true; | 262 gIR->irDsymbol[sd].irStruct->hasUnions = true; |
263 i->second.var->irField->index = idx; | 263 gIR->irDsymbol[i->second.var].irField->index = idx; |
264 i->second.var->irField->indexOffset = (i->first - lastoffset) / s; | 264 gIR->irDsymbol[i->second.var].irField->indexOffset = (i->first - lastoffset) / s; |
265 } | 265 } |
266 // fresh offset | 266 // fresh offset |
267 else { | 267 else { |
268 // commit the field | 268 // commit the field |
269 fieldtypes.push_back(fieldtype); | 269 fieldtypes.push_back(fieldtype); |
279 // start new | 279 // start new |
280 lastoffset = i->first; | 280 lastoffset = i->first; |
281 fieldtype = i->second.type; | 281 fieldtype = i->second.type; |
282 fieldinit = i->second.var; | 282 fieldinit = i->second.var; |
283 prevsize = getABITypeSize(fieldtype); | 283 prevsize = getABITypeSize(fieldtype); |
284 i->second.var->irField->index = idx; | 284 gIR->irDsymbol[i->second.var].irField->index = idx; |
285 fieldpad = 0; | 285 fieldpad = 0; |
286 } | 286 } |
287 } | 287 } |
288 fieldtypes.push_back(fieldtype); | 288 fieldtypes.push_back(fieldtype); |
289 irstruct->defaultFields.push_back(fieldinit); | 289 irstruct->defaultFields.push_back(fieldinit); |
318 | 318 |
319 ////////////////////////////////////////////////////////////////////////////////////////// | 319 ////////////////////////////////////////////////////////////////////////////////////////// |
320 | 320 |
321 void DtoDeclareStruct(StructDeclaration* sd) | 321 void DtoDeclareStruct(StructDeclaration* sd) |
322 { | 322 { |
323 if (sd->llvmDeclared) return; | 323 if (gIR->irDsymbol[sd].declared) return; |
324 sd->llvmDeclared = true; | 324 gIR->irDsymbol[sd].declared = true; |
325 | 325 |
326 Logger::println("DtoDeclareStruct(%s): %s", sd->toChars(), sd->loc.toChars()); | 326 Logger::println("DtoDeclareStruct(%s): %s", sd->toChars(), sd->loc.toChars()); |
327 LOG_SCOPE; | 327 LOG_SCOPE; |
328 | 328 |
329 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); | 329 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); |
332 initname.append(sd->mangle()); | 332 initname.append(sd->mangle()); |
333 initname.append("6__initZ"); | 333 initname.append("6__initZ"); |
334 | 334 |
335 llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd); | 335 llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd); |
336 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); | 336 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); |
337 sd->irStruct->init = initvar; | 337 gIR->irDsymbol[sd].irStruct->init = initvar; |
338 | 338 |
339 gIR->constInitList.push_back(sd); | 339 gIR->constInitList.push_back(sd); |
340 if (sd->getModule() == gIR->dmodule) | 340 if (sd->getModule() == gIR->dmodule) |
341 gIR->defineList.push_back(sd); | 341 gIR->defineList.push_back(sd); |
342 } | 342 } |
343 | 343 |
344 ////////////////////////////////////////////////////////////////////////////////////////// | 344 ////////////////////////////////////////////////////////////////////////////////////////// |
345 | 345 |
346 void DtoConstInitStruct(StructDeclaration* sd) | 346 void DtoConstInitStruct(StructDeclaration* sd) |
347 { | 347 { |
348 if (sd->llvmInitialized) return; | 348 if (gIR->irDsymbol[sd].initialized) return; |
349 sd->llvmInitialized = true; | 349 gIR->irDsymbol[sd].initialized = true; |
350 | 350 |
351 Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars()); | 351 Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars()); |
352 LOG_SCOPE; | 352 LOG_SCOPE; |
353 | 353 |
354 IrStruct* irstruct = sd->irStruct; | 354 IrStruct* irstruct = gIR->irDsymbol[sd].irStruct; |
355 gIR->structs.push_back(irstruct); | 355 gIR->structs.push_back(irstruct); |
356 | 356 |
357 // make sure each offset knows its default initializer | 357 // make sure each offset knows its default initializer |
358 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) | 358 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) |
359 { | 359 { |
360 IrStruct::Offset* so = &i->second; | 360 IrStruct::Offset* so = &i->second; |
361 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); | 361 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); |
362 so->init = finit; | 362 so->init = finit; |
363 so->var->irField->constInit = finit; | 363 gIR->irDsymbol[so->var].irField->constInit = finit; |
364 } | 364 } |
365 | 365 |
366 const llvm::StructType* structtype = isaStruct(sd->type->llvmType->get()); | 366 const llvm::StructType* structtype = isaStruct(sd->type->llvmType->get()); |
367 | 367 |
368 // go through the field inits and build the default initializer | 368 // go through the field inits and build the default initializer |
369 std::vector<llvm::Constant*> fieldinits_ll; | 369 std::vector<llvm::Constant*> fieldinits_ll; |
370 size_t nfi = irstruct->defaultFields.size(); | 370 size_t nfi = irstruct->defaultFields.size(); |
371 for (size_t i=0; i<nfi; ++i) { | 371 for (size_t i=0; i<nfi; ++i) { |
372 llvm::Constant* c; | 372 llvm::Constant* c; |
373 if (irstruct->defaultFields[i] != NULL) { | 373 if (irstruct->defaultFields[i] != NULL) { |
374 c = irstruct->defaultFields[i]->irField->constInit; | 374 c = gIR->irDsymbol[irstruct->defaultFields[i]].irField->constInit; |
375 assert(c); | 375 assert(c); |
376 } | 376 } |
377 else { | 377 else { |
378 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i)); | 378 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i)); |
379 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); | 379 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); |
381 } | 381 } |
382 fieldinits_ll.push_back(c); | 382 fieldinits_ll.push_back(c); |
383 } | 383 } |
384 | 384 |
385 // generate the union mapper | 385 // generate the union mapper |
386 sd->irStruct->dunion = new DUnion; // uses gIR->topstruct() | 386 gIR->irDsymbol[sd].irStruct->dunion = new DUnion; // uses gIR->topstruct() |
387 | 387 |
388 // always generate the constant initalizer | 388 // always generate the constant initalizer |
389 if (!sd->zeroInit) { | 389 if (!sd->zeroInit) { |
390 Logger::println("Not zero initialized"); | 390 Logger::println("Not zero initialized"); |
391 //assert(tk == gIR->gIR->topstruct()().size()); | 391 //assert(tk == gIR->gIR->topstruct()().size()); |
397 Logger::cout() << "Value:" << '\n'; | 397 Logger::cout() << "Value:" << '\n'; |
398 Logger::cout() << *fieldinits_ll[k] << '\n'; | 398 Logger::cout() << *fieldinits_ll[k] << '\n'; |
399 } | 399 } |
400 Logger::cout() << "Initializer printed" << '\n'; | 400 Logger::cout() << "Initializer printed" << '\n'; |
401 #endif | 401 #endif |
402 sd->irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll); | 402 gIR->irDsymbol[sd].irStruct->constInit = llvm::ConstantStruct::get(structtype,fieldinits_ll); |
403 } | 403 } |
404 else { | 404 else { |
405 Logger::println("Zero initialized"); | 405 Logger::println("Zero initialized"); |
406 sd->irStruct->constInit = llvm::ConstantAggregateZero::get(structtype); | 406 gIR->irDsymbol[sd].irStruct->constInit = llvm::ConstantAggregateZero::get(structtype); |
407 } | 407 } |
408 | 408 |
409 gIR->structs.pop_back(); | 409 gIR->structs.pop_back(); |
410 | 410 |
411 // emit typeinfo | 411 // emit typeinfo |
415 | 415 |
416 ////////////////////////////////////////////////////////////////////////////////////////// | 416 ////////////////////////////////////////////////////////////////////////////////////////// |
417 | 417 |
418 void DtoDefineStruct(StructDeclaration* sd) | 418 void DtoDefineStruct(StructDeclaration* sd) |
419 { | 419 { |
420 if (sd->llvmDefined) return; | 420 if (gIR->irDsymbol[sd].defined) return; |
421 sd->llvmDefined = true; | 421 gIR->irDsymbol[sd].defined = true; |
422 | 422 |
423 Logger::println("DtoDefineStruct(%s): %s", sd->toChars(), sd->loc.toChars()); | 423 Logger::println("DtoDefineStruct(%s): %s", sd->toChars(), sd->loc.toChars()); |
424 LOG_SCOPE; | 424 LOG_SCOPE; |
425 | 425 |
426 assert(sd->type->ty == Tstruct); | 426 assert(sd->type->ty == Tstruct); |
427 TypeStruct* ts = (TypeStruct*)sd->type; | 427 TypeStruct* ts = (TypeStruct*)sd->type; |
428 sd->irStruct->init->setInitializer(sd->irStruct->constInit); | 428 gIR->irDsymbol[sd].irStruct->init->setInitializer(gIR->irDsymbol[sd].irStruct->constInit); |
429 | 429 |
430 sd->llvmDModule = gIR->dmodule; | 430 gIR->irDsymbol[sd].DModule = gIR->dmodule; |
431 } | 431 } |
432 | 432 |
433 ////////////////////////////////////////////////////////////////////////////////////////// | 433 ////////////////////////////////////////////////////////////////////////////////////////// |
434 //////////////////////////// D UNION HELPER CLASS //////////////////////////////////// | 434 //////////////////////////// D UNION HELPER CLASS //////////////////////////////////// |
435 ////////////////////////////////////////////////////////////////////////////////////////// | 435 ////////////////////////////////////////////////////////////////////////////////////////// |