Mercurial > projects > ldc
comparison gen/structs.cpp @ 213:7816aafeea3c trunk
[svn r229] Updated the object.d implementation to the latest Tango.
Fixed a bunch of the built-in typeinfos for arrays, they did not inherit TypeInfo_Array.
Applied patch to tango/text/convert/Layout.d by fvbommel, closes #47 .
Cleaned up some type code.
Replaced uses of llvm::Type with LLType (a typedef), same for Value and Constant.
Fixed a few cases where typeinfo for user structs could be emitted multiple times, seems to still be some cases of this :/
author | lindquist |
---|---|
date | Fri, 30 May 2008 19:32:04 +0200 |
parents | 9d44ec83acd1 |
children | 0806379a5eca |
comparison
equal
deleted
inserted
replaced
212:4c2689d57ba4 | 213:7816aafeea3c |
---|---|
15 | 15 |
16 #include "ir/irstruct.h" | 16 #include "ir/irstruct.h" |
17 | 17 |
18 ////////////////////////////////////////////////////////////////////////////////////////// | 18 ////////////////////////////////////////////////////////////////////////////////////////// |
19 | 19 |
20 const llvm::Type* DtoStructType(Type* t) | 20 const LLType* DtoStructType(Type* t) |
21 { | 21 { |
22 assert(0); | 22 assert(0); |
23 std::vector<const llvm::Type*> types; | 23 std::vector<const LLType*> types; |
24 return llvm::StructType::get(types); | 24 return llvm::StructType::get(types); |
25 } | 25 } |
26 | 26 |
27 ////////////////////////////////////////////////////////////////////////////////////////// | 27 ////////////////////////////////////////////////////////////////////////////////////////// |
28 | 28 |
29 llvm::Value* DtoStructZeroInit(llvm::Value* v) | 29 LLValue* DtoStructZeroInit(LLValue* v) |
30 { | 30 { |
31 assert(gIR); | 31 assert(gIR); |
32 uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0)); | 32 uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0)); |
33 //llvm::Type* sarrty = getPtrToType(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); | 33 //LLType* sarrty = getPtrToType(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); |
34 const llvm::Type* sarrty = getPtrToType(llvm::Type::Int8Ty); | 34 const LLType* sarrty = getPtrToType(llvm::Type::Int8Ty); |
35 | 35 |
36 llvm::Value* sarr = DtoBitCast(v, sarrty); | 36 LLValue* sarr = DtoBitCast(v, sarrty); |
37 | 37 |
38 llvm::Function* fn = LLVM_DeclareMemSet32(); | 38 llvm::Function* fn = LLVM_DeclareMemSet32(); |
39 std::vector<llvm::Value*> llargs; | 39 assert(fn); |
40 std::vector<LLValue*> llargs; | |
40 llargs.resize(4); | 41 llargs.resize(4); |
41 llargs[0] = sarr; | 42 llargs[0] = sarr; |
42 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | 43 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); |
43 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | 44 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); |
44 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 45 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
45 | 46 |
46 llvm::Value* ret = llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 47 LLValue* ret = llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
47 | 48 |
48 return ret; | 49 return ret; |
49 } | 50 } |
50 | 51 |
51 ////////////////////////////////////////////////////////////////////////////////////////// | 52 ////////////////////////////////////////////////////////////////////////////////////////// |
52 | 53 |
53 llvm::Value* DtoStructCopy(llvm::Value* dst, llvm::Value* src) | 54 LLValue* DtoStructCopy(LLValue* dst, LLValue* src) |
54 { | 55 { |
55 Logger::cout() << "dst = " << *dst << " src = " << *src << '\n'; | 56 Logger::cout() << "dst = " << *dst << " src = " << *src << '\n'; |
56 assert(dst->getType() == src->getType()); | 57 assert(dst->getType() == src->getType()); |
57 assert(gIR); | 58 assert(gIR); |
58 | 59 |
59 uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0)); | 60 uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0)); |
60 //llvm::Type* sarrty = getPtrToType(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); | 61 //LLType* sarrty = getPtrToType(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); |
61 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); | 62 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); |
62 | 63 |
63 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | 64 LLValue* dstarr = DtoBitCast(dst,arrty); |
64 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); | 65 LLValue* srcarr = DtoBitCast(src,arrty); |
65 | 66 |
66 llvm::Function* fn = LLVM_DeclareMemCpy32(); | 67 llvm::Function* fn = LLVM_DeclareMemCpy32(); |
67 std::vector<llvm::Value*> llargs; | 68 std::vector<LLValue*> llargs; |
68 llargs.resize(4); | 69 llargs.resize(4); |
69 llargs[0] = dstarr; | 70 llargs[0] = dstarr; |
70 llargs[1] = srcarr; | 71 llargs[1] = srcarr; |
71 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | 72 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); |
72 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 73 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
73 | 74 |
74 return llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 75 return llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
75 } | 76 } |
76 | 77 |
77 ////////////////////////////////////////////////////////////////////////////////////////// | 78 ////////////////////////////////////////////////////////////////////////////////////////// |
78 llvm::Constant* DtoConstStructInitializer(StructInitializer* si) | 79 LLConstant* DtoConstStructInitializer(StructInitializer* si) |
79 { | 80 { |
80 Logger::println("DtoConstStructInitializer: %s", si->toChars()); | 81 Logger::println("DtoConstStructInitializer: %s", si->toChars()); |
81 LOG_SCOPE; | 82 LOG_SCOPE; |
82 | 83 |
83 TypeStruct* ts = (TypeStruct*)si->ad->type; | 84 TypeStruct* ts = (TypeStruct*)si->ad->type; |
92 { | 93 { |
93 Initializer* ini = (Initializer*)si->value.data[i]; | 94 Initializer* ini = (Initializer*)si->value.data[i]; |
94 assert(ini); | 95 assert(ini); |
95 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; | 96 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; |
96 assert(vd); | 97 assert(vd); |
97 llvm::Constant* v = DtoConstInitializer(vd->type, ini); | 98 LLConstant* v = DtoConstInitializer(vd->type, ini); |
98 inits.push_back(DUnionIdx(vd->ir.irField->index, vd->ir.irField->indexOffset, v)); | 99 inits.push_back(DUnionIdx(vd->ir.irField->index, vd->ir.irField->indexOffset, v)); |
99 } | 100 } |
100 | 101 |
101 DtoConstInitStruct((StructDeclaration*)si->ad); | 102 DtoConstInitStruct((StructDeclaration*)si->ad); |
102 return si->ad->ir.irStruct->dunion->getConst(inits); | 103 return si->ad->ir.irStruct->dunion->getConst(inits); |
103 } | 104 } |
104 | 105 |
105 ////////////////////////////////////////////////////////////////////////////////////////// | 106 ////////////////////////////////////////////////////////////////////////////////////////// |
106 | 107 |
107 llvm::Value* DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs) | 108 LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs) |
108 { | 109 { |
109 Logger::println("checking for offset %u type %s:", os, t->toChars()); | 110 Logger::println("checking for offset %u type %s:", os, t->toChars()); |
110 LOG_SCOPE; | 111 LOG_SCOPE; |
111 | 112 |
112 if (idxs.empty()) | 113 if (idxs.empty()) |
113 idxs.push_back(0); | 114 idxs.push_back(0); |
114 | 115 |
115 const llvm::Type* llt = getPtrToType(DtoType(t)); | 116 const LLType* llt = getPtrToType(DtoType(t)); |
116 const llvm::Type* st = getPtrToType(DtoType(sd->type)); | 117 const LLType* st = getPtrToType(DtoType(sd->type)); |
117 if (ptr->getType() != st) { | 118 if (ptr->getType() != st) { |
118 assert(sd->ir.irStruct->hasUnions); | 119 assert(sd->ir.irStruct->hasUnions); |
119 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); | 120 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); |
120 } | 121 } |
121 | 122 |
145 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); | 146 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); |
146 std::vector<unsigned> tmp; | 147 std::vector<unsigned> tmp; |
147 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | 148 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
148 } | 149 } |
149 else { | 150 else { |
150 const llvm::Type* sty = getPtrToType(DtoType(vd->type)); | 151 const LLType* sty = getPtrToType(DtoType(vd->type)); |
151 if (ptr->getType() != sty) { | 152 if (ptr->getType() != sty) { |
152 ptr = DtoBitCast(ptr, sty); | 153 ptr = DtoBitCast(ptr, sty); |
153 std::vector<unsigned> tmp; | 154 std::vector<unsigned> tmp; |
154 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | 155 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
155 } | 156 } |
219 }*/ | 220 }*/ |
220 | 221 |
221 Logger::println("doing struct fields"); | 222 Logger::println("doing struct fields"); |
222 | 223 |
223 const llvm::StructType* structtype = 0; | 224 const llvm::StructType* structtype = 0; |
224 std::vector<const llvm::Type*> fieldtypes; | 225 std::vector<const LLType*> fieldtypes; |
225 | 226 |
226 if (irstruct->offsets.empty()) | 227 if (irstruct->offsets.empty()) |
227 { | 228 { |
228 Logger::println("has no fields"); | 229 Logger::println("has no fields"); |
229 fieldtypes.push_back(llvm::Type::Int8Ty); | 230 fieldtypes.push_back(llvm::Type::Int8Ty); |
232 else | 233 else |
233 { | 234 { |
234 Logger::println("has fields"); | 235 Logger::println("has fields"); |
235 unsigned prevsize = (unsigned)-1; | 236 unsigned prevsize = (unsigned)-1; |
236 unsigned lastoffset = (unsigned)-1; | 237 unsigned lastoffset = (unsigned)-1; |
237 const llvm::Type* fieldtype = NULL; | 238 const LLType* fieldtype = NULL; |
238 VarDeclaration* fieldinit = NULL; | 239 VarDeclaration* fieldinit = NULL; |
239 size_t fieldpad = 0; | 240 size_t fieldpad = 0; |
240 int idx = 0; | 241 int idx = 0; |
241 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { | 242 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { |
242 // first iteration | 243 // first iteration |
359 | 360 |
360 // make sure each offset knows its default initializer | 361 // make sure each offset knows its default initializer |
361 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) | 362 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) |
362 { | 363 { |
363 IrStruct::Offset* so = &i->second; | 364 IrStruct::Offset* so = &i->second; |
364 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); | 365 LLConstant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); |
365 so->init = finit; | 366 so->init = finit; |
366 so->var->ir.irField->constInit = finit; | 367 so->var->ir.irField->constInit = finit; |
367 } | 368 } |
368 | 369 |
369 const llvm::StructType* structtype = isaStruct(sd->type->ir.type->get()); | 370 const llvm::StructType* structtype = isaStruct(sd->type->ir.type->get()); |
370 | 371 |
371 // go through the field inits and build the default initializer | 372 // go through the field inits and build the default initializer |
372 std::vector<llvm::Constant*> fieldinits_ll; | 373 std::vector<LLConstant*> fieldinits_ll; |
373 size_t nfi = irstruct->defaultFields.size(); | 374 size_t nfi = irstruct->defaultFields.size(); |
374 for (size_t i=0; i<nfi; ++i) { | 375 for (size_t i=0; i<nfi; ++i) { |
375 llvm::Constant* c; | 376 LLConstant* c; |
376 if (irstruct->defaultFields[i] != NULL) { | 377 if (irstruct->defaultFields[i] != NULL) { |
377 c = irstruct->defaultFields[i]->ir.irField->constInit; | 378 c = irstruct->defaultFields[i]->ir.irField->constInit; |
378 assert(c); | 379 assert(c); |
379 } | 380 } |
380 else { | 381 else { |
381 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i)); | 382 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i)); |
382 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); | 383 std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); |
383 c = llvm::ConstantArray::get(arrty, vals); | 384 c = llvm::ConstantArray::get(arrty, vals); |
384 } | 385 } |
385 fieldinits_ll.push_back(c); | 386 fieldinits_ll.push_back(c); |
386 } | 387 } |
387 | 388 |
444 bool unions = false; | 445 bool unions = false; |
445 for (IrStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i) | 446 for (IrStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i) |
446 { | 447 { |
447 unsigned o = i->first; | 448 unsigned o = i->first; |
448 IrStruct::Offset* so = &i->second; | 449 IrStruct::Offset* so = &i->second; |
449 const llvm::Type* ft = so->init->getType(); | 450 const LLType* ft = so->init->getType(); |
450 size_t sz = getABITypeSize(ft); | 451 size_t sz = getABITypeSize(ft); |
451 if (f == NULL) { // new field | 452 if (f == NULL) { // new field |
452 fields.push_back(DUnionField()); | 453 fields.push_back(DUnionField()); |
453 f = &fields.back(); | 454 f = &fields.back(); |
454 f->size = sz; | 455 f->size = sz; |
492 } | 493 } |
493 Logger::println("******** DUnion END"); | 494 Logger::println("******** DUnion END"); |
494 }*/ | 495 }*/ |
495 } | 496 } |
496 | 497 |
497 static void push_nulls(size_t nbytes, std::vector<llvm::Constant*>& out) | 498 static void push_nulls(size_t nbytes, std::vector<LLConstant*>& out) |
498 { | 499 { |
499 assert(nbytes > 0); | 500 assert(nbytes > 0); |
500 std::vector<llvm::Constant*> i(nbytes, llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); | 501 std::vector<LLConstant*> i(nbytes, llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); |
501 out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(llvm::Type::Int8Ty, nbytes), i)); | 502 out.push_back(llvm::ConstantArray::get(llvm::ArrayType::get(llvm::Type::Int8Ty, nbytes), i)); |
502 } | 503 } |
503 | 504 |
504 llvm::Constant* DUnion::getConst(std::vector<DUnionIdx>& in) | 505 LLConstant* DUnion::getConst(std::vector<DUnionIdx>& in) |
505 { | 506 { |
506 std::sort(in.begin(), in.end()); | 507 std::sort(in.begin(), in.end()); |
507 std::vector<llvm::Constant*> out; | 508 std::vector<LLConstant*> out; |
508 | 509 |
509 size_t nin = in.size(); | 510 size_t nin = in.size(); |
510 size_t nfields = fields.size(); | 511 size_t nfields = fields.size(); |
511 | 512 |
512 size_t fi = 0; | 513 size_t fi = 0; |
559 os = 0; | 560 os = 0; |
560 continue; | 561 continue; |
561 } | 562 } |
562 } | 563 } |
563 | 564 |
564 std::vector<const llvm::Type*> tys; | 565 std::vector<const LLType*> tys; |
565 size_t nout = out.size(); | 566 size_t nout = out.size(); |
566 for (size_t i=0; i<nout; ++i) | 567 for (size_t i=0; i<nout; ++i) |
567 tys.push_back(out[i]->getType()); | 568 tys.push_back(out[i]->getType()); |
568 | 569 |
569 const llvm::StructType* st = llvm::StructType::get(tys); | 570 const llvm::StructType* st = llvm::StructType::get(tys); |