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:
Alexey Prokhin 2011-02-20 19:00:45 +03:00
parent 600a3100c0
commit 6d89bfa961
7 changed files with 127 additions and 38 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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)
{

View file

@ -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());

View file

@ -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;
}
//////////////////////////////////////////////////////////////////////////////////////////

View file

@ -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)