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 #if DMDV2
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGetX":"_aaInX"); llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGetX":"_aaInX");
#else #else
llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaIn"); llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, lvalue?"_aaGet":"_aaIn");
#endif #endif
const llvm::FunctionType* funcTy = func->getFunctionType(); 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"); res = gIR->ir->CreateNot(res, "tmp");
return res; 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) void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* exp)
{ {
Logger::println("DtoCatAssignElement"); 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"); gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray");
} }
#endif
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
#if DMDV2 #if DMDV2

View file

@ -295,6 +295,8 @@ int linkObjToExecutable(const char* argv0)
// default libs // default libs
switch(global.params.os) { switch(global.params.os) {
case OSLinux: case OSLinux:
args.push_back("-lrt");
// fallthrough
case OSMacOSX: case OSMacOSX:
args.push_back("-ldl"); args.push_back("-ldl");
// fallthrough // 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, fname, M);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
} }
// D1:
// byte[] _d_arrayappendcT(TypeInfo ti, void* array, void* element) #if DMDV2
// D2: // byte[] _d_arrayappendcTX(TypeInfo ti, ref byte[] px, size_t n)
// byte[] _d_arrayappendcT(TypeInfo ti, byte[]* array, byte* element)
{ {
llvm::StringRef fname("_d_arrayappendcT"); llvm::StringRef fname("_d_arrayappendcTX");
std::vector<const LLType*> types; std::vector<const LLType*> types;
types.push_back(typeInfoTy); types.push_back(typeInfoTy);
#if DMDV2
types.push_back(voidArrayPtrTy); types.push_back(voidArrayPtrTy);
#else types.push_back(sizeTy);
types.push_back(voidPtrTy);
#endif
types.push_back(voidPtrTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); 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, fname, M);
} }
#if DMDV2
// void[] _d_arrayappendT(TypeInfo ti, byte[]* px, byte[] y) // void[] _d_arrayappendT(TypeInfo ti, byte[]* px, byte[] y)
{ {
llvm::StringRef fname("_d_arrayappendT"); llvm::StringRef fname("_d_arrayappendT");
@ -446,6 +439,17 @@ static void LLVM_D_BuildRuntimeModule()
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); 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, 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 #endif
// Object _d_allocclass(ClassInfo ci) // Object _d_allocclass(ClassInfo ci)
@ -959,6 +963,16 @@ static void LLVM_D_BuildRuntimeModule()
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
->setAttributes(Attr_1_2_NoCapture); ->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 #else
// int _aaEq(AA aa, AA ab, TypeInfo_AssociativeArray ti) // 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 // repaint the type if necessary
if (resulttype) if (resulttype)
{ {
Type* rbase = resulttype->toBasetype(); Type* rbase = stripModifiers(resulttype->toBasetype());
Type* nextbase = tf->nextOf()->toBasetype(); Type* nextbase = stripModifiers(tf->nextOf()->toBasetype());
#if DMDV2
rbase = rbase->mutableOf();
nextbase = nextbase->mutableOf();
#endif
if (!rbase->equals(nextbase)) if (!rbase->equals(nextbase))
{ {
Logger::println("repainting return value from '%s' to '%s'", tf->nextOf()->toChars(), rbase->toChars()); 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) if (cachedLvalue)
{ {
LLValue* V = cachedLvalue; LLValue* V = cachedLvalue;
#if DMDV1
cachedLvalue = NULL; cachedLvalue = NULL;
#endif
return new DVarValue(type, V); return new DVarValue(type, V);
} }
@ -595,6 +597,15 @@ static Expression* findLvalue(IRState* irs, Expression* exp)
return e; 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) \ #define BIN_ASSIGN(X) \
DValue* X##AssignExp::toElem(IRState* p) \ DValue* X##AssignExp::toElem(IRState* p) \
{ \ { \
@ -604,6 +615,7 @@ DValue* X##AssignExp::toElem(IRState* p) \
e3.type = e1->type; \ e3.type = e1->type; \
DValue* dst = findLvalue(p, e1)->toElem(p); \ DValue* dst = findLvalue(p, e1)->toElem(p); \
DValue* res = e3.toElem(p); \ DValue* res = e3.toElem(p); \
CLEAR_CACHED_LVALUE \
DValue* stval = DtoCast(loc, res, dst->getType()); \ DValue* stval = DtoCast(loc, res, dst->getType()); \
DtoAssign(loc, dst, stval); \ DtoAssign(loc, dst, stval); \
return DtoCast(loc, res, type); \ return DtoCast(loc, res, type); \
@ -1138,7 +1150,9 @@ DValue* PtrExp::toElem(IRState* p)
if (cachedLvalue) if (cachedLvalue)
{ {
V = cachedLvalue; V = cachedLvalue;
#if DMDV1
cachedLvalue = NULL; cachedLvalue = NULL;
#endif
} }
else else
{ {
@ -1165,7 +1179,9 @@ DValue* DotVarExp::toElem(IRState* p)
{ {
Logger::println("using cached lvalue"); Logger::println("using cached lvalue");
LLValue *V = cachedLvalue; LLValue *V = cachedLvalue;
#if DMDV1
cachedLvalue = NULL; cachedLvalue = NULL;
#endif
VarDeclaration* vd = var->isVarDeclaration(); VarDeclaration* vd = var->isVarDeclaration();
assert(vd); assert(vd);
return new DVarValue(type, vd, V); return new DVarValue(type, vd, V);
@ -1304,7 +1320,9 @@ DValue* IndexExp::toElem(IRState* p)
if (cachedLvalue) if (cachedLvalue)
{ {
LLValue* V = cachedLvalue; LLValue* V = cachedLvalue;
#if DMDV1
cachedLvalue = NULL; cachedLvalue = NULL;
#endif
return new DVarValue(type, V); return new DVarValue(type, V);
} }
@ -2281,6 +2299,9 @@ DValue* CommaExp::toElem(IRState* p)
if (cachedLvalue) if (cachedLvalue)
{ {
LLValue* V = cachedLvalue; LLValue* V = cachedLvalue;
#if DMDV1
cachedLvalue = NULL;
#endif
return new DVarValue(type, V); return new DVarValue(type, V);
} }
@ -2817,6 +2838,45 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p)
Type* aatype = type->toBasetype(); Type* aatype = type->toBasetype();
Type* vtype = aatype->nextOf(); 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 // it should be possible to avoid the temporary in some cases
LLValue* tmp = DtoAlloca(type,"aaliteral"); LLValue* tmp = DtoAlloca(type,"aaliteral");
DValue* aa = new DVarValue(type, tmp); DValue* aa = new DVarValue(type, tmp);
@ -2839,26 +2899,10 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p)
DtoAssign(loc, mem, val); DtoAssign(loc, mem, val);
} }
#if DMDV2 return aa;
// 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();
// 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 #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 CORE_D_STDC ${RUNTIME_DIR}/src/core/stdc/*.d )
file(GLOB_RECURSE GC_D ${RUNTIME_GC_DIR}/*.d) file(GLOB_RECURSE GC_D ${RUNTIME_GC_DIR}/*.d)
file(GLOB_RECURSE DCRT_D ${RUNTIME_DC_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 list(REMOVE_ITEM DCRT_D
${RUNTIME_DC_DIR}/arraybyte.d ${RUNTIME_DC_DIR}/arraybyte.d
${RUNTIME_DC_DIR}/arraycast.d ${RUNTIME_DC_DIR}/arraycast.d
@ -77,7 +78,9 @@ elseif(D_VERSION EQUAL 2)
${RUNTIME_DC_DIR}/arrayfloat.d ${RUNTIME_DC_DIR}/arrayfloat.d
${RUNTIME_DC_DIR}/arrayreal.d ${RUNTIME_DC_DIR}/arrayreal.d
${RUNTIME_DC_DIR}/arrayshort.d ${RUNTIME_DC_DIR}/arrayshort.d
${RUNTIME_DC_DIR}/deh.d
${RUNTIME_DC_DIR}/deh2.d ${RUNTIME_DC_DIR}/deh2.d
${RUNTIME_DC_DIR}/trace.d
) )
file(GLOB DCRT_C ${RUNTIME_DC_DIR}/*.c) file(GLOB DCRT_C ${RUNTIME_DC_DIR}/*.c)
list(REMOVE_ITEM DCRT_C ${RUNTIME_DC_DIR}/deh.c ${RUNTIME_DC_DIR}/memory_osx.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) elseif(APPLE)
file(GLOB_RECURSE CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/osx/*.d) file(GLOB_RECURSE CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/osx/*.d)
endif(UNIX) 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/object_.d
${RUNTIME_DIR}/src/std/intrinsic.d
) )
file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c) file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c)