mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Use druntime functions for array operations
This commit is contained in:
3573
druntime.patch
3573
druntime.patch
File diff suppressed because it is too large
Load Diff
122
gen/arrays.cpp
122
gen/arrays.cpp
@@ -214,15 +214,8 @@ void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr)
|
||||
Logger::println("SetArray");
|
||||
LLValue *arr = array->getLVal();
|
||||
assert(isaStruct(arr->getType()->getContainedType(0)));
|
||||
#if 1
|
||||
DtoStore(dim, DtoGEPi(arr,0,0));
|
||||
DtoStore(ptr, DtoGEPi(arr,0,1));
|
||||
#else
|
||||
DSliceValue *slice = DtoResizeDynArray(array->type, array, dim);
|
||||
DtoMemCpy(DtoArrayPtr(array), ptr, dim);
|
||||
DtoStore(dim, DtoGEPi(arr,0,0));
|
||||
DtoStore(slice->ptr, DtoGEPi(arr,0,1));
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -424,6 +417,24 @@ static bool isInitialized(Type* et) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static DSliceValue *getSlice(Type *arrayType, LLValue *array)
|
||||
{
|
||||
// Get ptr and length of the array
|
||||
LLValue* newArrayLVal = DtoRawAlloca(array->getType(), 0, "newArray");
|
||||
DtoStore(array, newArrayLVal);
|
||||
LLValue* arrayLen = DtoLoad(DtoGEPi(newArrayLVal,0,0));
|
||||
LLValue* newptr = DtoLoad(DtoGEPi(newArrayLVal,0,1));
|
||||
|
||||
// cast pointer to wanted type
|
||||
const LLType* dstType = DtoType(arrayType)->getContainedType(1);
|
||||
if (newptr->getType() != dstType)
|
||||
newptr = DtoBitCast(newptr, dstType, ".gc_mem");
|
||||
|
||||
return new DSliceValue(arrayType, arrayLen, newptr);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit)
|
||||
{
|
||||
@@ -442,11 +453,24 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default
|
||||
if (defaultInit && !isInitialized(eltType))
|
||||
defaultInit = false;
|
||||
bool zeroInit = eltType->isZeroInit();
|
||||
|
||||
#if DMDV2
|
||||
|
||||
const char* fnname = zeroInit ? "_d_newarrayT" : "_d_newarrayiT";
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname);
|
||||
|
||||
// call allocator
|
||||
LLValue* newArray = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction();
|
||||
|
||||
return getSlice(arrayType, newArray);
|
||||
|
||||
#else
|
||||
|
||||
const char* fnname = defaultInit ? (zeroInit ? "_d_newarrayT" : "_d_newarrayiT") : "_d_newarrayvT";
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname);
|
||||
|
||||
// call allocator
|
||||
LLValue* newptr = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction();
|
||||
LLValue* array = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem").getInstruction();
|
||||
|
||||
// cast to wanted type
|
||||
const LLType* dstType = DtoType(arrayType)->getContainedType(1);
|
||||
@@ -457,6 +481,9 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default
|
||||
Logger::cout() << "final ptr = " << *newptr << '\n';
|
||||
|
||||
return new DSliceValue(arrayType, arrayLen, newptr);
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -525,18 +552,29 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim)
|
||||
LLSmallVector<LLValue*,4> args;
|
||||
args.push_back(DtoTypeInfoOf(arrayType));
|
||||
args.push_back(newdim);
|
||||
args.push_back(DtoArrayLen(array));
|
||||
|
||||
#if DMDV2
|
||||
|
||||
args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(2)));
|
||||
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem").getInstruction();
|
||||
|
||||
return getSlice(arrayType, newArray);
|
||||
|
||||
#else
|
||||
|
||||
LLValue* arrPtr = DtoArrayPtr(array);
|
||||
args.push_back(DtoArrayLen(array));
|
||||
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "arrPtr = " << *arrPtr << '\n';
|
||||
args.push_back(DtoBitCast(arrPtr, fn->getFunctionType()->getParamType(3), "tmp"));
|
||||
|
||||
LLValue* newptr = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".gc_mem").getInstruction();
|
||||
if (newptr->getType() != arrPtr->getType())
|
||||
newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem");
|
||||
|
||||
return new DSliceValue(arrayType, newdim, newptr);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -559,6 +597,36 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if DMDV2
|
||||
|
||||
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp)
|
||||
{
|
||||
Logger::println("DtoCatAssignArray");
|
||||
LOG_SCOPE;
|
||||
Type *arrayType = arr->getType();
|
||||
DValue* valueToAppend = exp->toElem(gIR);
|
||||
|
||||
// Prepare arguments
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendT");
|
||||
LLSmallVector<LLValue*,3> args;
|
||||
// TypeInfo ti
|
||||
args.push_back(DtoTypeInfoOf(arrayType));
|
||||
// byte[] *px
|
||||
args.push_back(DtoBitCast(arr->getLVal(), fn->getFunctionType()->getParamType(1)));
|
||||
// byte[] y
|
||||
LLValue *y = makeLValue(exp->loc, valueToAppend);
|
||||
y = DtoBitCast(y, getPtrToType(fn->getFunctionType()->getParamType(2)));
|
||||
args.push_back(DtoLoad(y));
|
||||
|
||||
// Call _d_arrayappendT
|
||||
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction();
|
||||
|
||||
return getSlice(arrayType, newArray);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp)
|
||||
{
|
||||
Logger::println("DtoCatAssignArray");
|
||||
@@ -589,7 +657,39 @@ DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp)
|
||||
return slice;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if DMDV2
|
||||
|
||||
DSliceValue* DtoCatArrays(Type* arrayType, Expression* exp1, Expression* exp2)
|
||||
{
|
||||
Logger::println("DtoCatAssignArray");
|
||||
LOG_SCOPE;
|
||||
|
||||
// Prepare arguments
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arraycatT");
|
||||
LLSmallVector<LLValue*,3> args;
|
||||
// TypeInfo ti
|
||||
args.push_back(DtoTypeInfoOf(arrayType));
|
||||
// byte[] x
|
||||
LLValue *val = makeLValue(exp1->loc, exp1->toElem(gIR));
|
||||
val = DtoBitCast(val, getPtrToType(fn->getFunctionType()->getParamType(1)));
|
||||
args.push_back(DtoLoad(val));
|
||||
// byte[] y
|
||||
val = makeLValue(exp2->loc, exp2->toElem(gIR));
|
||||
val = DtoBitCast(val, getPtrToType(fn->getFunctionType()->getParamType(2)));
|
||||
args.push_back(DtoLoad(val));
|
||||
|
||||
// Call _d_arraycatT
|
||||
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction();
|
||||
|
||||
return getSlice(arrayType, newArray);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
DSliceValue* DtoCatArrays(Type* type, Expression* exp1, Expression* exp2)
|
||||
{
|
||||
Logger::println("DtoCatArrays");
|
||||
@@ -630,6 +730,8 @@ DSliceValue* DtoCatArrays(Type* type, Expression* exp1, Expression* exp2)
|
||||
return slice;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2)
|
||||
{
|
||||
|
||||
@@ -175,7 +175,9 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
|
||||
Logger::println("building aggr types");
|
||||
const LLType* voidPtrTy = rt_ptr(byteTy);
|
||||
const LLType* stringTy = rt_array(byteTy);
|
||||
const LLType* voidArrayTy = rt_array(byteTy);
|
||||
const LLType* voidArrayPtrTy = getPtrToType(voidArrayTy);
|
||||
const LLType* stringTy = voidArrayTy;
|
||||
const LLType* wstringTy = rt_array(shortTy);
|
||||
const LLType* dstringTy = rt_array(intTy);
|
||||
|
||||
@@ -271,7 +273,7 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
|
||||
->setAttributes(Attr_NoAlias);
|
||||
}
|
||||
|
||||
#if DMDV1
|
||||
// void* _d_newarrayT(TypeInfo ti, size_t length)
|
||||
// void* _d_newarrayiT(TypeInfo ti, size_t length)
|
||||
// void* _d_newarrayvT(TypeInfo ti, size_t length)
|
||||
@@ -290,6 +292,20 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M)
|
||||
->setAttributes(Attr_NoAlias);
|
||||
}
|
||||
#else
|
||||
// void[] _d_newarrayT(TypeInfo ti, size_t length)
|
||||
// void[] _d_newarrayiT(TypeInfo ti, size_t length)
|
||||
{
|
||||
llvm::StringRef fname("_d_newarrayT");
|
||||
llvm::StringRef fname2("_d_newarrayiT");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(sizeTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
#endif
|
||||
|
||||
// void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims)
|
||||
// void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims)
|
||||
@@ -311,32 +327,71 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
->setAttributes(Attr_NoAlias_3_NoCapture);
|
||||
}
|
||||
|
||||
// D1:
|
||||
// void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
|
||||
// void* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
|
||||
// D2:
|
||||
// void[] _d_arraysetlengthT(TypeInfo ti, size_t newlength, void[] *array)
|
||||
// void[] _d_arraysetlengthiT(TypeInfo ti, size_t newlength, void[] *array)
|
||||
{
|
||||
llvm::StringRef fname("_d_arraysetlengthT");
|
||||
llvm::StringRef fname2("_d_arraysetlengthiT");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(sizeTy);
|
||||
#if DMDV2
|
||||
types.push_back(voidArrayPtrTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
|
||||
#else
|
||||
types.push_back(sizeTy);
|
||||
types.push_back(voidPtrTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||
#endif
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
|
||||
// void* _d_arrayappendcT(TypeInfo ti, void* array, void* element)
|
||||
// D1:
|
||||
// byte[] _d_arrayappendcT(TypeInfo ti, void* array, void* element)
|
||||
// D2:
|
||||
// byte[] _d_arrayappendcT(TypeInfo ti, byte[]* array, byte* element)
|
||||
{
|
||||
llvm::StringRef fname("_d_arrayappendcT");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
#if DMDV2
|
||||
types.push_back(voidArrayPtrTy);
|
||||
#else
|
||||
types.push_back(voidPtrTy);
|
||||
#endif
|
||||
types.push_back(voidPtrTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(rt_array(byteTy), types, false);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
}
|
||||
|
||||
#if DMDV2
|
||||
// void[] _d_arrayappendT(TypeInfo ti, byte[]* px, byte[] y)
|
||||
{
|
||||
llvm::StringRef fname("_d_arrayappendT");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(voidArrayPtrTy);
|
||||
types.push_back(voidArrayTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
}
|
||||
|
||||
// byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y)
|
||||
{
|
||||
llvm::StringRef fname("_d_arraycatT");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(voidArrayTy);
|
||||
types.push_back(voidArrayTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Object _d_allocclass(ClassInfo ci)
|
||||
{
|
||||
llvm::StringRef fname(_d_allocclass);
|
||||
|
||||
Reference in New Issue
Block a user