# HG changeset patch # User lindquist # Date 1212962470 -7200 # Node ID 0db62b770a49e755073827525069287cc375e375 # Parent fa691b1c0498690f46ffec2c9ceecbb93fcabda1 [svn r257] Fixed: array .sort and .reverse runtime code was incorrect. Fixed: most runtime calls did not get correct param attrs. diff -r fa691b1c0498 -r 0db62b770a49 gen/functions.cpp --- a/gen/functions.cpp Sun Jun 08 22:07:10 2008 +0200 +++ b/gen/functions.cpp Mon Jun 09 00:01:10 2008 +0200 @@ -319,6 +319,54 @@ ////////////////////////////////////////////////////////////////////////////////////////// +static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl) +{ + assert(f->parameters); + + int llidx = 1; + if (f->llvmRetInPtr) ++llidx; + if (f->llvmUsesThis) ++llidx; + if (f->linkage == LINKd && f->varargs == 1) + llidx += 2; + + int funcNumArgs = func->getArgumentList().size(); + std::vector attrs; + int k = 0; + + int nbyval = 0; + + if (fdecl->isMain() && Argument::dim(f->parameters) == 0) + { + llvm::ParamAttrsWithIndex PAWI; + PAWI.Index = llidx; + PAWI.Attrs = llvm::ParamAttr::ByVal; + attrs.push_back(PAWI); + llidx++; + nbyval++; + } + + for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k) + { + Argument* fnarg = (Argument*)f->parameters->data[k]; + assert(fnarg); + if (fnarg->llvmByVal) + { + llvm::ParamAttrsWithIndex PAWI; + PAWI.Index = llidx; + PAWI.Attrs = llvm::ParamAttr::ByVal; + attrs.push_back(PAWI); + nbyval++; + } + } + + if (nbyval) { + llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end()); + func->setParamAttrs(palist); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + void DtoDeclareFunction(FuncDeclaration* fdecl) { if (fdecl->ir.declared) return; @@ -335,11 +383,18 @@ fatal(); } + // get TypeFunction* + Type* t = DtoDType(fdecl->type); + TypeFunction* f = (TypeFunction*)t; + + // runtime function special handling if (fdecl->runTimeHack) { Logger::println("runtime hack func chars: %s", fdecl->toChars()); if (!fdecl->ir.irFunc) { - fdecl->ir.irFunc = new IrFunction(fdecl); - fdecl->ir.irFunc->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); + IrFunction* irfunc = new IrFunction(fdecl); + llvm::Function* llfunc = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); + fdecl->ir.irFunc = irfunc; + fdecl->ir.irFunc->func = llfunc; } return; } @@ -372,9 +427,6 @@ vafunc = DtoDeclareVaFunction(fdecl); } - Type* t = DtoDType(fdecl->type); - TypeFunction* f = (TypeFunction*)t; - // construct function const llvm::FunctionType* functype = DtoFunctionType(fdecl); llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name); @@ -396,50 +448,8 @@ assert(llvm::isa(f->ir.type->get())); // parameter attributes - if (f->parameters) - { - int llidx = 1; - if (f->llvmRetInPtr) ++llidx; - if (f->llvmUsesThis) ++llidx; - if (f->linkage == LINKd && f->varargs == 1) - llidx += 2; - - int funcNumArgs = func->getArgumentList().size(); - std::vector attrs; - int k = 0; - - int nbyval = 0; - - if (fdecl->isMain() && Argument::dim(f->parameters) == 0) - { - llvm::ParamAttrsWithIndex PAWI; - PAWI.Index = llidx; - PAWI.Attrs = llvm::ParamAttr::ByVal; - attrs.push_back(PAWI); - llidx++; - nbyval++; - } - - for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k) - { - Argument* fnarg = (Argument*)f->parameters->data[k]; - assert(fnarg); - if (fnarg->llvmByVal) - { - llvm::ParamAttrsWithIndex PAWI; - PAWI.Index = llidx; - PAWI.Attrs = llvm::ParamAttr::ByVal; - attrs.push_back(PAWI); - nbyval++; - } - } - - //warning("set %d byval args for function: %s", nbyval, func->getName().c_str()); - - if (nbyval) { - llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end()); - func->setParamAttrs(palist); - } + if (f->parameters) { + set_param_attrs(f, func, fdecl); } // main diff -r fa691b1c0498 -r 0db62b770a49 gen/runtime.cpp --- a/gen/runtime.cpp Sun Jun 08 22:07:10 2008 +0200 +++ b/gen/runtime.cpp Mon Jun 09 00:01:10 2008 +0200 @@ -97,7 +97,9 @@ } const llvm::FunctionType* fnty = fn->getFunctionType(); - return llvm::cast(target->getOrInsertFunction(name, fnty)); + llvm::Function* resfn = llvm::cast(target->getOrInsertFunction(name, fnty)); + resfn->setParamAttrs(fn->getParamAttrs()); + return resfn; } ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -217,9 +219,11 @@ types.push_back(stringTy); types.push_back(intTy); const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - 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, fname3, M); + llvm::PAListPtr palist; + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setParamAttrs(palist); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M)->setParamAttrs(palist); } // void _d_assert_msg( char[] msg, char[] file, uint line ) @@ -230,7 +234,10 @@ types.push_back(stringTy); types.push_back(intTy); const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } ///////////////////////////////////////////////////////////////////////////////////// @@ -361,6 +368,7 @@ ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// + // int _aApplycd1(char[] aa, dg_t dg) #define STR_APPLY1(TY,a,b) \ { \ std::string fname(a); \ @@ -369,14 +377,18 @@ types.push_back(TY); \ types.push_back(rt_dg1()); \ const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + llvm::PAListPtr palist; \ + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); \ + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setParamAttrs(palist); \ } STR_APPLY1(stringTy, "_aApplycw1", "_aApplycd1") STR_APPLY1(wstringTy, "_aApplywc1", "_aApplywd1") STR_APPLY1(dstringTy, "_aApplydc1", "_aApplydw1") #undef STR_APPLY + // int _aApplycd2(char[] aa, dg2_t dg) #define STR_APPLY2(TY,a,b) \ { \ std::string fname(a); \ @@ -385,8 +397,11 @@ types.push_back(TY); \ types.push_back(rt_dg2()); \ const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + llvm::PAListPtr palist; \ + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); \ + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setParamAttrs(palist); \ } STR_APPLY2(stringTy, "_aApplycw2", "_aApplycd2") STR_APPLY2(wstringTy, "_aApplywc2", "_aApplywd2") @@ -401,8 +416,11 @@ types.push_back(TY); \ types.push_back(rt_dg1()); \ const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + llvm::PAListPtr palist; \ + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); \ + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setParamAttrs(palist); \ } STR_APPLY_R1(stringTy, "_aApplyRcw1", "_aApplyRcd1") STR_APPLY_R1(wstringTy, "_aApplyRwc1", "_aApplyRwd1") @@ -417,8 +435,11 @@ types.push_back(TY); \ types.push_back(rt_dg2()); \ const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); \ - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); \ + llvm::PAListPtr palist; \ + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); \ + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); \ + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setParamAttrs(palist); \ } STR_APPLY_R2(stringTy, "_aApplyRcw2", "_aApplyRcd2") STR_APPLY_R2(wstringTy, "_aApplyRwc2", "_aApplyRwd2") @@ -506,8 +527,10 @@ types.push_back(stringTy); types.push_back(stringTy); const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); + llvm::PAListPtr palist; + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setParamAttrs(palist); } // wchar[] _adReverseWchar(wchar[] a) @@ -519,8 +542,10 @@ types.push_back(wstringTy); types.push_back(wstringTy); const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); + llvm::PAListPtr palist; + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setParamAttrs(palist); } // Array _adReverse(Array a, size_t szelem) @@ -531,7 +556,9 @@ types.push_back(rt_array(byteTy)); types.push_back(sizeTy); const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } // Array _adDupT(TypeInfo ti, Array a) @@ -542,7 +569,9 @@ types.push_back(typeInfoTy); types.push_back(rt_array(byteTy)); const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(3, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } // int _adEq(Array a1, Array a2, TypeInfo ti) @@ -555,8 +584,11 @@ types.push_back(rt_array(byteTy)); types.push_back(typeInfoTy); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); + llvm::PAListPtr palist; + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M)->setParamAttrs(palist); } // int _adCmpChar(Array a1, Array a2) @@ -566,7 +598,10 @@ types.push_back(rt_array(byteTy)); types.push_back(rt_array(byteTy)); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } // Array _adSort(Array a, TypeInfo ti) @@ -577,7 +612,9 @@ types.push_back(rt_array(byteTy)); types.push_back(typeInfoTy); const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } ///////////////////////////////////////////////////////////////////////////////////// @@ -680,7 +717,9 @@ types.push_back(sizeTy); types.push_back(rt_dg1()); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(3, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } // int _aaApply2(AA aa, size_t keysize, dg2_t dg) @@ -691,7 +730,9 @@ types.push_back(sizeTy); types.push_back(rt_dg1()); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(3, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } ///////////////////////////////////////////////////////////////////////////////////// @@ -766,7 +807,10 @@ types.push_back(rt_array(rt_array2(byteTy))); types.push_back(stringTy); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } // int _d_switch_ustring(wchar[][] table, wchar[] ca) @@ -776,7 +820,10 @@ types.push_back(rt_array(rt_array2(shortTy))); types.push_back(wstringTy); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } // int _d_switch_dstring(dchar[][] table, dchar[] ca) @@ -786,7 +833,10 @@ types.push_back(rt_array(rt_array2(intTy))); types.push_back(dstringTy); const llvm::FunctionType* fty = llvm::FunctionType::get(intTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::PAListPtr palist; + palist = palist.addAttr(1, llvm::ParamAttr::ByVal); + palist = palist.addAttr(2, llvm::ParamAttr::ByVal); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist); } } diff -r fa691b1c0498 -r 0db62b770a49 gen/toir.cpp --- a/gen/toir.cpp Sun Jun 08 22:07:10 2008 +0200 +++ b/gen/toir.cpp Mon Jun 09 00:01:10 2008 +0200 @@ -1200,6 +1200,11 @@ // this hack is necessary :/ if (dfn && dfn->func && dfn->func->runTimeHack) { + llvm::Function* fn = dfn->func->ir.irFunc->func; + assert(fn); + if (fn->getParamAttrs().paramHasAttr(j+1, llvm::ParamAttr::ByVal)) + palist = palist.addAttr(j+1, llvm::ParamAttr::ByVal); + if (llfnty->getParamType(j) != NULL) { if (llargs[j]->getType() != llfnty->getParamType(j)) { Logger::println("llvmRunTimeHack==true - force casting argument"); diff -r fa691b1c0498 -r 0db62b770a49 tango/lib/compiler/llvmdc/adi.d --- a/tango/lib/compiler/llvmdc/adi.d Sun Jun 08 22:07:10 2008 +0200 +++ b/tango/lib/compiler/llvmdc/adi.d Mon Jun 09 00:01:10 2008 +0200 @@ -67,7 +67,7 @@ * reversed. */ -extern (C) long _adReverseChar(char[] a) +extern (C) Array _adReverseChar(char[] a) { if (a.length > 1) { @@ -127,7 +127,7 @@ hi = hi - 1 + (stridehi - stridelo); } } - return *cast(long*)(&a); + return Array(a.length, a.ptr); } unittest @@ -162,7 +162,7 @@ * reversed. */ -extern (C) long _adReverseWchar(wchar[] a) +extern (C) Array _adReverseWchar(wchar[] a) { if (a.length > 1) { @@ -220,7 +220,7 @@ hi = hi - 1 + (stridehi - stridelo); } } - return *cast(long*)(&a); + return Array(a.length, a.ptr); } unittest @@ -245,10 +245,10 @@ * Support for array.reverse property. */ -extern (C) long _adReverse(Array a, size_t szelem) +extern (C) Array _adReverse(Array a, size_t szelem) out (result) { - assert(result is *cast(long*)(&a)); + assert(result.ptr is a.ptr); } body { @@ -287,7 +287,7 @@ //gc_free(tmp); } } - return *cast(long*)(&a); + return Array(a.length, a.ptr); } unittest @@ -331,7 +331,7 @@ * Sort array of chars. */ -extern (C) long _adSortChar(char[] a) +extern (C) Array _adSortChar(char[] a) { if (a.length > 1) { @@ -346,14 +346,14 @@ } delete da; } - return *cast(long*)(&a); + return Array(a.length, a.ptr); } /********************************************** * Sort array of wchars. */ -extern (C) long _adSortWchar(wchar[] a) +extern (C) Array _adSortWchar(wchar[] a) { if (a.length > 1) { @@ -368,7 +368,7 @@ } delete da; } - return *cast(long*)(&a); + return Array(a.length, a.ptr); } /***************************************