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 //////////////////////////////////////////////////////////////////////////////////////////