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