mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-13 06:28:52 +03:00
[svn r359] Try to fix DtoArrayInit. Unfinished, breaks for arrays of primitive types.
This commit is contained in:
parent
b8bde8c0b8
commit
c67753508b
1 changed files with 62 additions and 61 deletions
123
gen/arrays.cpp
123
gen/arrays.cpp
|
@ -108,15 +108,16 @@ void DtoArrayAssign(LLValue* dst, LLValue* src)
|
||||||
|
|
||||||
typedef const LLType* constLLVMTypeP;
|
typedef const LLType* constLLVMTypeP;
|
||||||
|
|
||||||
static size_t checkRectArrayInit(const LLType* pt, constLLVMTypeP& finalty)
|
static size_t checkRectArrayInit(const LLType* pt, const LLType* t)
|
||||||
{
|
{
|
||||||
if (const LLArrayType* arrty = isaArray(pt)) {
|
const LLArrayType* arrty = isaArray(pt);
|
||||||
size_t n = checkRectArrayInit(arrty->getElementType(), finalty);
|
if (pt != t && arrty) {
|
||||||
|
size_t n = checkRectArrayInit(arrty->getElementType(), t);
|
||||||
size_t ne = arrty->getNumElements();
|
size_t ne = arrty->getNumElements();
|
||||||
if (n) return n * ne;
|
if (n) return n * ne;
|
||||||
return ne;
|
return ne;
|
||||||
}
|
}
|
||||||
finalty = pt;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,72 +134,19 @@ void DtoArrayInit(DValue* array, DValue* value)
|
||||||
|
|
||||||
const LLType* pt = ptr->getType()->getContainedType(0);
|
const LLType* pt = ptr->getType()->getContainedType(0);
|
||||||
const LLType* t = val->getType();
|
const LLType* t = val->getType();
|
||||||
const LLType* finalTy;
|
|
||||||
|
|
||||||
size_t aggrsz = 0;
|
size_t aggrsz = 0;
|
||||||
Type* valtype = value->getType()->toBasetype();
|
Type* valtype = value->getType()->toBasetype();
|
||||||
|
|
||||||
// handle rectangular init
|
const char* funcname = NULL;
|
||||||
if (size_t arrsz = checkRectArrayInit(pt, finalTy))
|
|
||||||
{
|
|
||||||
assert(finalTy == t);
|
|
||||||
LLConstant* c = isaConstant(dim);
|
|
||||||
assert(c);
|
|
||||||
dim = llvm::ConstantExpr::getMul(c, DtoConstSize_t(arrsz));
|
|
||||||
ptr = gIR->ir->CreateBitCast(ptr, getPtrToType(finalTy), "tmp");
|
|
||||||
}
|
|
||||||
// handle null aggregate
|
|
||||||
else if (isaStruct(t))
|
|
||||||
{
|
|
||||||
aggrsz = getABITypeSize(t);
|
|
||||||
LLConstant* c = isaConstant(val);
|
|
||||||
assert(c && c->isNullValue());
|
|
||||||
LLValue* nbytes;
|
|
||||||
if (aggrsz == 1)
|
|
||||||
nbytes = dim;
|
|
||||||
else
|
|
||||||
nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp");
|
|
||||||
DtoMemSetZero(ptr,nbytes);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// handle general aggregate case
|
|
||||||
else if (DtoIsPassedByRef(valtype))
|
|
||||||
{
|
|
||||||
aggrsz = getABITypeSize(pt);
|
|
||||||
ptr = gIR->ir->CreateBitCast(ptr, getVoidPtrType(), "tmp");
|
|
||||||
val = gIR->ir->CreateBitCast(val, getVoidPtrType(), "tmp");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger::cout() << "no special handling" << '\n';
|
|
||||||
assert(t == pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n';
|
|
||||||
|
|
||||||
LLSmallVector<LLValue*, 4> args;
|
LLSmallVector<LLValue*, 4> args;
|
||||||
args.push_back(ptr);
|
args.push_back(ptr);
|
||||||
args.push_back(dim);
|
args.push_back(dim);
|
||||||
args.push_back(val);
|
args.push_back(val);
|
||||||
|
|
||||||
const char* funcname = NULL;
|
// if t is a primitive type, use the corresponding runtime function
|
||||||
|
if (t == LLType::Int1Ty) {
|
||||||
if (aggrsz) {
|
|
||||||
funcname = "_d_array_init_mem";
|
|
||||||
args.push_back(DtoConstSize_t(aggrsz));
|
|
||||||
}
|
|
||||||
else if (isaPointer(t)) {
|
|
||||||
funcname = "_d_array_init_pointer";
|
|
||||||
|
|
||||||
const LLType* dstty = getPtrToType(getPtrToType(LLType::Int8Ty));
|
|
||||||
if (args[0]->getType() != dstty)
|
|
||||||
args[0] = DtoBitCast(args[0],dstty);
|
|
||||||
|
|
||||||
const LLType* valty = getPtrToType(LLType::Int8Ty);
|
|
||||||
if (args[2]->getType() != valty)
|
|
||||||
args[2] = DtoBitCast(args[2],valty);
|
|
||||||
}
|
|
||||||
else if (t == LLType::Int1Ty) {
|
|
||||||
funcname = "_d_array_init_i1";
|
funcname = "_d_array_init_i1";
|
||||||
}
|
}
|
||||||
else if (t == LLType::Int8Ty) {
|
else if (t == LLType::Int8Ty) {
|
||||||
|
@ -219,7 +167,60 @@ void DtoArrayInit(DValue* array, DValue* value)
|
||||||
else if (t == LLType::DoubleTy) {
|
else if (t == LLType::DoubleTy) {
|
||||||
funcname = "_d_array_init_double";
|
funcname = "_d_array_init_double";
|
||||||
}
|
}
|
||||||
else {
|
else if (t == getPtrToType(LLType::Int8Ty)) {
|
||||||
|
funcname = "_d_array_init_pointer";
|
||||||
|
|
||||||
|
const LLType* dstty = getPtrToType(getVoidPtrType());
|
||||||
|
if (args[0]->getType() != dstty)
|
||||||
|
args[0] = DtoBitCast(args[0],dstty);
|
||||||
|
|
||||||
|
const LLType* valty = getVoidPtrType();
|
||||||
|
if (args[2]->getType() != valty)
|
||||||
|
args[2] = DtoBitCast(args[2],valty);
|
||||||
|
}
|
||||||
|
// handle array rhs
|
||||||
|
else if (value->getType()->ty == Tarray || value->getType()->ty == Tsarray)
|
||||||
|
{
|
||||||
|
const LLArrayType* dstarrty = isaArray(pt);
|
||||||
|
assert(dstarrty);
|
||||||
|
const LLPointerType* srcty = isaPointer(t);
|
||||||
|
assert(dstarrty == srcty->getElementType());
|
||||||
|
|
||||||
|
funcname = "_d_array_init_mem";
|
||||||
|
|
||||||
|
args[0] = gIR->ir->CreateBitCast(ptr, getVoidPtrType(), "tmp");
|
||||||
|
args[2] = gIR->ir->CreateBitCast(val, getVoidPtrType(), "tmp");
|
||||||
|
|
||||||
|
size_t n_inner = getABITypeSize(srcty->getElementType());
|
||||||
|
args.push_back(DtoConstSize_t(n_inner));
|
||||||
|
}
|
||||||
|
// handle null aggregate
|
||||||
|
else if (isaStruct(t))
|
||||||
|
{
|
||||||
|
aggrsz = getABITypeSize(t);
|
||||||
|
LLConstant* c = isaConstant(val);
|
||||||
|
assert(c && c->isNullValue());
|
||||||
|
LLValue* nbytes;
|
||||||
|
if (aggrsz == 1)
|
||||||
|
nbytes = dim;
|
||||||
|
else
|
||||||
|
nbytes = gIR->ir->CreateMul(dim, DtoConstSize_t(aggrsz), "tmp");
|
||||||
|
DtoMemSetZero(ptr,nbytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// handle general aggregate case
|
||||||
|
else if (DtoIsPassedByRef(valtype))
|
||||||
|
{
|
||||||
|
funcname = "_d_array_init_mem";
|
||||||
|
|
||||||
|
args[0] = gIR->ir->CreateBitCast(ptr, getVoidPtrType(), "tmp");
|
||||||
|
args[2] = gIR->ir->CreateBitCast(val, getVoidPtrType(), "tmp");
|
||||||
|
|
||||||
|
aggrsz = getABITypeSize(pt);
|
||||||
|
args.push_back(DtoConstSize_t(aggrsz));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Logger::cout() << *ptr->getType() << " = " << *val->getType() << '\n';
|
Logger::cout() << *ptr->getType() << " = " << *val->getType() << '\n';
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue