comparison gen/structs.cpp @ 136:0e28624814e8 trunk

[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
author lindquist
date Thu, 17 Jan 2008 03:15:12 +0100
parents 44a95ac7368a
children ce7b81fb957f
comparison
equal deleted inserted replaced
135:176bd52b3cf5 136:0e28624814e8
10 #include "gen/irstate.h" 10 #include "gen/irstate.h"
11 #include "gen/tollvm.h" 11 #include "gen/tollvm.h"
12 #include "gen/arrays.h" 12 #include "gen/arrays.h"
13 #include "gen/logger.h" 13 #include "gen/logger.h"
14 #include "gen/structs.h" 14 #include "gen/structs.h"
15
16 #include "ir/irstruct.h"
15 17
16 ////////////////////////////////////////////////////////////////////////////////////////// 18 //////////////////////////////////////////////////////////////////////////////////////////
17 19
18 const llvm::Type* DtoStructType(Type* t) 20 const llvm::Type* DtoStructType(Type* t)
19 { 21 {
91 Initializer* ini = (Initializer*)si->value.data[i]; 93 Initializer* ini = (Initializer*)si->value.data[i];
92 assert(ini); 94 assert(ini);
93 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; 95 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i];
94 assert(vd); 96 assert(vd);
95 llvm::Constant* v = DtoConstInitializer(vd->type, ini); 97 llvm::Constant* v = DtoConstInitializer(vd->type, ini);
96 inits.push_back(DUnionIdx(vd->llvmFieldIndex, vd->llvmFieldIndexOffset, v)); 98 inits.push_back(DUnionIdx(vd->irField->index, vd->irField->indexOffset, v));
97 } 99 }
98 100
99 DtoConstInitStruct((StructDeclaration*)si->ad); 101 DtoConstInitStruct((StructDeclaration*)si->ad);
100 return si->ad->llvmUnion->getConst(inits); 102 return si->ad->llvmUnion->getConst(inits);
101 } 103 }
119 121
120 for (unsigned i=0; i<sd->fields.dim; ++i) { 122 for (unsigned i=0; i<sd->fields.dim; ++i) {
121 VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i]; 123 VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i];
122 Type* vdtype = DtoDType(vd->type); 124 Type* vdtype = DtoDType(vd->type);
123 Logger::println("found %u type %s", vd->offset, vdtype->toChars()); 125 Logger::println("found %u type %s", vd->offset, vdtype->toChars());
124 assert(vd->llvmFieldIndex >= 0); 126 assert(vd->irField->index >= 0);
125 if (os == vd->offset && vdtype == t) { 127 if (os == vd->offset && vdtype == t) {
126 idxs.push_back(vd->llvmFieldIndex); 128 idxs.push_back(vd->irField->index);
127 ptr = DtoGEP(ptr, idxs, "tmp"); 129 ptr = DtoGEP(ptr, idxs, "tmp");
128 if (ptr->getType() != llt) 130 if (ptr->getType() != llt)
129 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 131 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
130 if (vd->llvmFieldIndexOffset) 132 if (vd->irField->indexOffset)
131 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); 133 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
132 return ptr; 134 return ptr;
133 } 135 }
134 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { 136 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
135 TypeStruct* ts = (TypeStruct*)vdtype; 137 TypeStruct* ts = (TypeStruct*)vdtype;
136 StructDeclaration* ssd = ts->sym; 138 StructDeclaration* ssd = ts->sym;
137 idxs.push_back(vd->llvmFieldIndex); 139 idxs.push_back(vd->irField->index);
138 if (vd->llvmFieldIndexOffset) { 140 if (vd->irField->indexOffset) {
139 Logger::println("has union field offset"); 141 Logger::println("has union field offset");
140 ptr = DtoGEP(ptr, idxs, "tmp"); 142 ptr = DtoGEP(ptr, idxs, "tmp");
141 if (ptr->getType() != llt) 143 if (ptr->getType() != llt)
142 ptr = DtoBitCast(ptr, llt); 144 ptr = DtoBitCast(ptr, llt);
143 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); 145 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
144 std::vector<unsigned> tmp; 146 std::vector<unsigned> tmp;
145 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 147 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
146 } 148 }
147 else { 149 else {
148 const llvm::Type* sty = getPtrToType(DtoType(vd->type)); 150 const llvm::Type* sty = getPtrToType(DtoType(vd->type));
174 Logger::println("DtoResolveStruct(%s): %s", sd->toChars(), sd->loc.toChars()); 176 Logger::println("DtoResolveStruct(%s): %s", sd->toChars(), sd->loc.toChars());
175 LOG_SCOPE; 177 LOG_SCOPE;
176 178
177 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); 179 TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
178 180
179 IRStruct* irstruct = new IRStruct(ts); 181 IrStruct* irstruct = new IrStruct(ts);
180 sd->llvmIRStruct = irstruct; 182 sd->llvmIrStruct = irstruct;
181 gIR->structs.push_back(irstruct); 183 gIR->structs.push_back(irstruct);
182 184
183 // fields 185 // fields
184 Array* arr = &sd->fields; 186 Array* arr = &sd->fields;
185 for (int k=0; k < arr->dim; k++) { 187 for (int k=0; k < arr->dim; k++) {
231 unsigned lastoffset = (unsigned)-1; 233 unsigned lastoffset = (unsigned)-1;
232 const llvm::Type* fieldtype = NULL; 234 const llvm::Type* fieldtype = NULL;
233 VarDeclaration* fieldinit = NULL; 235 VarDeclaration* fieldinit = NULL;
234 size_t fieldpad = 0; 236 size_t fieldpad = 0;
235 int idx = 0; 237 int idx = 0;
236 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 238 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
237 // first iteration 239 // first iteration
238 if (lastoffset == (unsigned)-1) { 240 if (lastoffset == (unsigned)-1) {
239 lastoffset = i->first; 241 lastoffset = i->first;
240 assert(lastoffset == 0); 242 assert(lastoffset == 0);
241 fieldtype = i->second.type; 243 fieldtype = i->second.type;
242 fieldinit = i->second.var; 244 fieldinit = i->second.var;
243 prevsize = getABITypeSize(fieldtype); 245 prevsize = getABITypeSize(fieldtype);
244 i->second.var->llvmFieldIndex = idx; 246 i->second.var->irField->index = idx;
245 } 247 }
246 // colliding offset? 248 // colliding offset?
247 else if (lastoffset == i->first) { 249 else if (lastoffset == i->first) {
248 size_t s = getABITypeSize(i->second.type); 250 size_t s = getABITypeSize(i->second.type);
249 if (s > prevsize) { 251 if (s > prevsize) {
250 fieldpad += s - prevsize; 252 fieldpad += s - prevsize;
251 prevsize = s; 253 prevsize = s;
252 } 254 }
253 sd->llvmHasUnions = true; 255 sd->llvmHasUnions = true;
254 i->second.var->llvmFieldIndex = idx; 256 i->second.var->irField->index = idx;
255 } 257 }
256 // intersecting offset? 258 // intersecting offset?
257 else if (i->first < (lastoffset + prevsize)) { 259 else if (i->first < (lastoffset + prevsize)) {
258 size_t s = getABITypeSize(i->second.type); 260 size_t s = getABITypeSize(i->second.type);
259 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
260 sd->llvmHasUnions = true; 262 sd->llvmHasUnions = true;
261 i->second.var->llvmFieldIndex = idx; 263 i->second.var->irField->index = idx;
262 i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s; 264 i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
263 } 265 }
264 // fresh offset 266 // fresh offset
265 else { 267 else {
266 // commit the field 268 // commit the field
267 fieldtypes.push_back(fieldtype); 269 fieldtypes.push_back(fieldtype);
277 // start new 279 // start new
278 lastoffset = i->first; 280 lastoffset = i->first;
279 fieldtype = i->second.type; 281 fieldtype = i->second.type;
280 fieldinit = i->second.var; 282 fieldinit = i->second.var;
281 prevsize = getABITypeSize(fieldtype); 283 prevsize = getABITypeSize(fieldtype);
282 i->second.var->llvmFieldIndex = idx; 284 i->second.var->irField->index = idx;
283 fieldpad = 0; 285 fieldpad = 0;
284 } 286 }
285 } 287 }
286 fieldtypes.push_back(fieldtype); 288 fieldtypes.push_back(fieldtype);
287 irstruct->defaultFields.push_back(fieldinit); 289 irstruct->defaultFields.push_back(fieldinit);
347 sd->llvmInitialized = true; 349 sd->llvmInitialized = true;
348 350
349 Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars()); 351 Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars());
350 LOG_SCOPE; 352 LOG_SCOPE;
351 353
352 IRStruct* irstruct = sd->llvmIRStruct; 354 IrStruct* irstruct = sd->llvmIrStruct;
353 gIR->structs.push_back(irstruct); 355 gIR->structs.push_back(irstruct);
354 356
355 // make sure each offset knows its default initializer 357 // make sure each offset knows its default initializer
356 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)
357 { 359 {
358 IRStruct::Offset* so = &i->second; 360 IrStruct::Offset* so = &i->second;
359 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); 361 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
360 so->init = finit; 362 so->init = finit;
361 so->var->llvmConstInit = finit; 363 so->var->irField->constInit = finit;
362 } 364 }
363 365
364 const llvm::StructType* structtype = isaStruct(sd->type->llvmType->get()); 366 const llvm::StructType* structtype = isaStruct(sd->type->llvmType->get());
365 367
366 // go through the field inits and build the default initializer 368 // go through the field inits and build the default initializer
367 std::vector<llvm::Constant*> fieldinits_ll; 369 std::vector<llvm::Constant*> fieldinits_ll;
368 size_t nfi = irstruct->defaultFields.size(); 370 size_t nfi = irstruct->defaultFields.size();
369 for (size_t i=0; i<nfi; ++i) { 371 for (size_t i=0; i<nfi; ++i) {
370 llvm::Constant* c; 372 llvm::Constant* c;
371 if (irstruct->defaultFields[i] != NULL) { 373 if (irstruct->defaultFields[i] != NULL) {
372 c = irstruct->defaultFields[i]->llvmConstInit; 374 c = irstruct->defaultFields[i]->irField->constInit;
373 assert(c); 375 assert(c);
374 } 376 }
375 else { 377 else {
376 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i)); 378 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i));
377 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));
433 ////////////////////////////////////////////////////////////////////////////////////////// 435 //////////////////////////////////////////////////////////////////////////////////////////
434 436
435 DUnion::DUnion() 437 DUnion::DUnion()
436 { 438 {
437 DUnionField* f = NULL; 439 DUnionField* f = NULL;
438 IRStruct* topstruct = gIR->topstruct(); 440 IrStruct* topstruct = gIR->topstruct();
439 bool unions = false; 441 bool unions = false;
440 for (IRStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i) 442 for (IrStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i)
441 { 443 {
442 unsigned o = i->first; 444 unsigned o = i->first;
443 IRStruct::Offset* so = &i->second; 445 IrStruct::Offset* so = &i->second;
444 const llvm::Type* ft = so->init->getType(); 446 const llvm::Type* ft = so->init->getType();
445 size_t sz = getABITypeSize(ft); 447 size_t sz = getABITypeSize(ft);
446 if (f == NULL) { // new field 448 if (f == NULL) { // new field
447 fields.push_back(DUnionField()); 449 fields.push_back(DUnionField());
448 f = &fields.back(); 450 f = &fields.back();