mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 17:11:44 +03:00
Use _d_assocarrayliteralTX to initialize associative arrays. Replace depricated _d_arrayappendcT() by _d_arrayappendcTX(). Make sure that a l-value of a binassign expressions is only evaluated once (reapllied 1784 but only for D2)
This commit is contained in:
parent
600a3100c0
commit
6d89bfa961
7 changed files with 127 additions and 38 deletions
|
@ -53,7 +53,6 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
|
|||
#if DMDV2
|
||||
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGetX":"_aaInX");
|
||||
#else
|
||||
|
||||
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaIn");
|
||||
#endif
|
||||
const llvm::FunctionType* funcTy = func->getFunctionType();
|
||||
|
@ -272,3 +271,5 @@ LLValue* DtoAAEquals(Loc& loc, TOK op, DValue* l, DValue* r)
|
|||
res = gIR->ir->CreateNot(res, "tmp");
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -723,6 +723,34 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim)
|
|||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
#if DMDV2
|
||||
|
||||
void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* exp)
|
||||
{
|
||||
Logger::println("DtoCatAssignElement");
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(array);
|
||||
|
||||
LLValue *oldLength = DtoArrayLen(array);
|
||||
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcTX");
|
||||
LLSmallVector<LLValue*,3> args;
|
||||
args.push_back(DtoTypeInfoOf(arrayType));
|
||||
args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(1)));
|
||||
args.push_back(DtoConstSize_t(1));
|
||||
|
||||
LLValue* appendedArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction();
|
||||
appendedArray = DtoAggrPaint(appendedArray, DtoType(arrayType));
|
||||
|
||||
LLValue* val = DtoExtractValue(appendedArray, 1, ".ptr");
|
||||
val = DtoGEP1(val, oldLength, "lastElem");
|
||||
val = DtoBitCast(val, DtoType(arrayType->nextOf()->pointerTo()));
|
||||
DtoAssign(loc, new DVarValue(arrayType->nextOf(), val), exp->toElem(gIR));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* exp)
|
||||
{
|
||||
Logger::println("DtoCatAssignElement");
|
||||
|
@ -741,6 +769,8 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e
|
|||
gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if DMDV2
|
||||
|
|
|
@ -295,6 +295,8 @@ int linkObjToExecutable(const char* argv0)
|
|||
// default libs
|
||||
switch(global.params.os) {
|
||||
case OSLinux:
|
||||
args.push_back("-lrt");
|
||||
// fallthrough
|
||||
case OSMacOSX:
|
||||
args.push_back("-ldl");
|
||||
// fallthrough
|
||||
|
|
|
@ -389,25 +389,18 @@ static void LLVM_D_BuildRuntimeModule()
|
|||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
// D1:
|
||||
// byte[] _d_arrayappendcT(TypeInfo ti, void* array, void* element)
|
||||
// D2:
|
||||
// byte[] _d_arrayappendcT(TypeInfo ti, byte[]* array, byte* element)
|
||||
|
||||
#if DMDV2
|
||||
// byte[] _d_arrayappendcTX(TypeInfo ti, ref byte[] px, size_t n)
|
||||
{
|
||||
llvm::StringRef fname("_d_arrayappendcT");
|
||||
llvm::StringRef fname("_d_arrayappendcTX");
|
||||
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);
|
||||
types.push_back(sizeTy);
|
||||
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");
|
||||
|
@ -446,6 +439,17 @@ static void LLVM_D_BuildRuntimeModule()
|
|||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
}
|
||||
#else // DMDV1
|
||||
// byte[] _d_arrayappendcT(TypeInfo ti, void* array, void* element)
|
||||
{
|
||||
llvm::StringRef fname("_d_arrayappendcT");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(voidPtrTy);
|
||||
types.push_back(voidPtrTy);
|
||||
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)
|
||||
|
@ -959,6 +963,16 @@ static void LLVM_D_BuildRuntimeModule()
|
|||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
|
||||
->setAttributes(Attr_1_2_NoCapture);
|
||||
}
|
||||
// BB* _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values)
|
||||
{
|
||||
llvm::StringRef fname("_d_assocarrayliteralTX");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(voidArrayTy);
|
||||
types.push_back(voidArrayTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
}
|
||||
#else
|
||||
// int _aaEq(AA aa, AA ab, TypeInfo_AssociativeArray ti)
|
||||
{
|
||||
|
|
|
@ -591,12 +591,8 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
// repaint the type if necessary
|
||||
if (resulttype)
|
||||
{
|
||||
Type* rbase = resulttype->toBasetype();
|
||||
Type* nextbase = tf->nextOf()->toBasetype();
|
||||
#if DMDV2
|
||||
rbase = rbase->mutableOf();
|
||||
nextbase = nextbase->mutableOf();
|
||||
#endif
|
||||
Type* rbase = stripModifiers(resulttype->toBasetype());
|
||||
Type* nextbase = stripModifiers(tf->nextOf()->toBasetype());
|
||||
if (!rbase->equals(nextbase))
|
||||
{
|
||||
Logger::println("repainting return value from '%s' to '%s'", tf->nextOf()->toChars(), rbase->toChars());
|
||||
|
|
78
gen/toir.cpp
78
gen/toir.cpp
|
@ -85,7 +85,9 @@ DValue* VarExp::toElem(IRState* p)
|
|||
if (cachedLvalue)
|
||||
{
|
||||
LLValue* V = cachedLvalue;
|
||||
#if DMDV1
|
||||
cachedLvalue = NULL;
|
||||
#endif
|
||||
return new DVarValue(type, V);
|
||||
}
|
||||
|
||||
|
@ -595,6 +597,15 @@ static Expression* findLvalue(IRState* irs, Expression* exp)
|
|||
return e;
|
||||
}
|
||||
|
||||
#if DMDV2
|
||||
#define CLEAR_CACHED_LVALUE \
|
||||
while(e1->op == TOKcast) \
|
||||
e1 = ((CastExp*)e1)->e1; \
|
||||
e1->cachedLvalue = NULL;
|
||||
#else
|
||||
#define CLEAR_CACHED_LVALUE
|
||||
#endif
|
||||
|
||||
#define BIN_ASSIGN(X) \
|
||||
DValue* X##AssignExp::toElem(IRState* p) \
|
||||
{ \
|
||||
|
@ -604,6 +615,7 @@ DValue* X##AssignExp::toElem(IRState* p) \
|
|||
e3.type = e1->type; \
|
||||
DValue* dst = findLvalue(p, e1)->toElem(p); \
|
||||
DValue* res = e3.toElem(p); \
|
||||
CLEAR_CACHED_LVALUE \
|
||||
DValue* stval = DtoCast(loc, res, dst->getType()); \
|
||||
DtoAssign(loc, dst, stval); \
|
||||
return DtoCast(loc, res, type); \
|
||||
|
@ -1138,7 +1150,9 @@ DValue* PtrExp::toElem(IRState* p)
|
|||
if (cachedLvalue)
|
||||
{
|
||||
V = cachedLvalue;
|
||||
#if DMDV1
|
||||
cachedLvalue = NULL;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1165,7 +1179,9 @@ DValue* DotVarExp::toElem(IRState* p)
|
|||
{
|
||||
Logger::println("using cached lvalue");
|
||||
LLValue *V = cachedLvalue;
|
||||
#if DMDV1
|
||||
cachedLvalue = NULL;
|
||||
#endif
|
||||
VarDeclaration* vd = var->isVarDeclaration();
|
||||
assert(vd);
|
||||
return new DVarValue(type, vd, V);
|
||||
|
@ -1304,7 +1320,9 @@ DValue* IndexExp::toElem(IRState* p)
|
|||
if (cachedLvalue)
|
||||
{
|
||||
LLValue* V = cachedLvalue;
|
||||
#if DMDV1
|
||||
cachedLvalue = NULL;
|
||||
#endif
|
||||
return new DVarValue(type, V);
|
||||
}
|
||||
|
||||
|
@ -2281,6 +2299,9 @@ DValue* CommaExp::toElem(IRState* p)
|
|||
if (cachedLvalue)
|
||||
{
|
||||
LLValue* V = cachedLvalue;
|
||||
#if DMDV1
|
||||
cachedLvalue = NULL;
|
||||
#endif
|
||||
return new DVarValue(type, V);
|
||||
}
|
||||
|
||||
|
@ -2817,6 +2838,45 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p)
|
|||
Type* aatype = type->toBasetype();
|
||||
Type* vtype = aatype->nextOf();
|
||||
|
||||
#if DMDV2
|
||||
|
||||
Type* indexType = ((TypeAArray*)aatype)->index;
|
||||
|
||||
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assocarrayliteralTX");
|
||||
const llvm::FunctionType* funcTy = func->getFunctionType();
|
||||
LLValue* aaTypeInfo = DtoTypeInfoOf(stripModifiers(aatype));
|
||||
|
||||
std::vector<LLConstant*> keysInits, valuesInits;
|
||||
for (size_t i = 0, n = keys->dim; i < n; ++i)
|
||||
{
|
||||
Expression* ekey = (Expression*)keys->data[i];
|
||||
Expression* eval = (Expression*)values->data[i];
|
||||
Logger::println("(%zu) aa[%s] = %s", i, ekey->toChars(), eval->toChars());
|
||||
keysInits.push_back(ekey->toConstElem(p));
|
||||
valuesInits.push_back(eval->toConstElem(p));
|
||||
}
|
||||
|
||||
LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
|
||||
|
||||
const LLArrayType* arrtype = LLArrayType::get(DtoType(indexType), keys->dim);
|
||||
LLConstant* initval = LLConstantArray::get(arrtype, keysInits);
|
||||
LLConstant* globalstore = new LLGlobalVariable(*gIR->module, arrtype, false, LLGlobalValue::InternalLinkage, initval, ".aaKeysStorage");
|
||||
LLConstant* slice = llvm::ConstantExpr::getGetElementPtr(globalstore, idxs, 2);
|
||||
slice = DtoConstSlice(DtoConstSize_t(keys->dim), slice);
|
||||
LLValue* keysArray = DtoAggrPaint(slice, funcTy->getParamType(1));
|
||||
|
||||
arrtype = LLArrayType::get(DtoType(vtype), values->dim);
|
||||
initval = LLConstantArray::get(arrtype, valuesInits);
|
||||
globalstore = new LLGlobalVariable(*gIR->module, arrtype, false, LLGlobalValue::InternalLinkage, initval, ".aaValuesStorage");
|
||||
slice = llvm::ConstantExpr::getGetElementPtr(globalstore, idxs, 2);
|
||||
slice = DtoConstSlice(DtoConstSize_t(keys->dim), slice);
|
||||
LLValue* valuesArray = DtoAggrPaint(slice, funcTy->getParamType(2));
|
||||
|
||||
LLValue* aa = gIR->CreateCallOrInvoke3(func, aaTypeInfo, keysArray, valuesArray, "aa").getInstruction();
|
||||
return new DImValue(type, aa);
|
||||
|
||||
#else
|
||||
|
||||
// it should be possible to avoid the temporary in some cases
|
||||
LLValue* tmp = DtoAlloca(type,"aaliteral");
|
||||
DValue* aa = new DVarValue(type, tmp);
|
||||
|
@ -2839,26 +2899,10 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p)
|
|||
DtoAssign(loc, mem, val);
|
||||
}
|
||||
|
||||
#if DMDV2
|
||||
// Rehash array
|
||||
if (keys->dim) {
|
||||
// first get the runtime function
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_aaRehash");
|
||||
const llvm::FunctionType* funcTy = fn->getFunctionType();
|
||||
return aa;
|
||||
|
||||
// aa param
|
||||
LLValue* aaval = DtoBitCast(tmp, funcTy->getParamType(0));
|
||||
|
||||
// keyti param
|
||||
LLValue* keyti = DtoTypeInfoOf(((TypeAArray*)aatype)->index, false);
|
||||
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
||||
|
||||
// Call function
|
||||
gIR->CreateCallOrInvoke2(fn, aaval, keyti, ".gc_mem").getInstruction();
|
||||
}
|
||||
#endif
|
||||
|
||||
return aa;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -69,6 +69,7 @@ elseif(D_VERSION EQUAL 2)
|
|||
file(GLOB CORE_D_STDC ${RUNTIME_DIR}/src/core/stdc/*.d )
|
||||
file(GLOB_RECURSE GC_D ${RUNTIME_GC_DIR}/*.d)
|
||||
file(GLOB_RECURSE DCRT_D ${RUNTIME_DC_DIR}/*.d)
|
||||
file(GLOB_RECURSE LDC_D ${RUNTIME_DIR}/src/ldc/*.d)
|
||||
list(REMOVE_ITEM DCRT_D
|
||||
${RUNTIME_DC_DIR}/arraybyte.d
|
||||
${RUNTIME_DC_DIR}/arraycast.d
|
||||
|
@ -77,7 +78,9 @@ elseif(D_VERSION EQUAL 2)
|
|||
${RUNTIME_DC_DIR}/arrayfloat.d
|
||||
${RUNTIME_DC_DIR}/arrayreal.d
|
||||
${RUNTIME_DC_DIR}/arrayshort.d
|
||||
${RUNTIME_DC_DIR}/deh.d
|
||||
${RUNTIME_DC_DIR}/deh2.d
|
||||
${RUNTIME_DC_DIR}/trace.d
|
||||
)
|
||||
file(GLOB DCRT_C ${RUNTIME_DC_DIR}/*.c)
|
||||
list(REMOVE_ITEM DCRT_C ${RUNTIME_DC_DIR}/deh.c ${RUNTIME_DC_DIR}/memory_osx.c)
|
||||
|
@ -88,9 +91,8 @@ elseif(D_VERSION EQUAL 2)
|
|||
elseif(APPLE)
|
||||
file(GLOB_RECURSE CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/osx/*.d)
|
||||
endif(UNIX)
|
||||
list(APPEND CORE_D ${CORE_D_SYNC} ${CORE_D_SYS} ${CORE_D_STDC}
|
||||
list(APPEND CORE_D ${CORE_D_SYNC} ${CORE_D_SYS} ${CORE_D_STDC} ${LDC_D}
|
||||
${RUNTIME_DIR}/src/object_.d
|
||||
${RUNTIME_DIR}/src/std/intrinsic.d
|
||||
)
|
||||
file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue