diff --git a/gen/aa.cpp b/gen/aa.cpp index 45433873..434e2f1d 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -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; } + + diff --git a/gen/arrays.cpp b/gen/arrays.cpp index bdedf81d..b3e71475 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -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 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 diff --git a/gen/linker.cpp b/gen/linker.cpp index 7af6a4dd..343f73bd 100644 --- a/gen/linker.cpp +++ b/gen/linker.cpp @@ -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 diff --git a/gen/runtime.cpp b/gen/runtime.cpp index 6c05fbba..fbf6de86 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -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 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 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 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) { diff --git a/gen/tocall.cpp b/gen/tocall.cpp index 206780f6..26cf03c1 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -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()); diff --git a/gen/toir.cpp b/gen/toir.cpp index 466113f1..f6830111 100644 --- a/gen/toir.cpp +++ b/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 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; } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index f4a368b0..451235af 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -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)