# HG changeset patch # User Tomas Lindquist Olsen # Date 1217638497 -7200 # Node ID 283d113d4753be6fc2ce8c6feb9d061c183ce95f # Parent 60332cd8530875c9a4e11bbda137758b8116091a Added generation of the llvm 'sret' parameter attribute where applicable. Fixed some wrong argument handling code when setting parameter attributes. Updated the tango unittest script in the tango patch, does not work yet, all modules don't compile... diff -r 60332cd85308 -r 283d113d4753 gen/functions.cpp --- a/gen/functions.cpp Sat Aug 02 01:23:53 2008 +0200 +++ b/gen/functions.cpp Sat Aug 02 02:54:57 2008 +0200 @@ -158,11 +158,10 @@ at = getPtrToType(DtoType(ltd)); Logger::cout() << "lazy updated to: " << *at << '\n'; paramvec.back() = at; + // lazy doesn't need byval as the delegate is not visible to the user } } - //warning("set %d byval args for type: %s", nbyval, f->toChars()); - // construct function type bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); @@ -306,8 +305,6 @@ 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; @@ -328,6 +325,14 @@ attrs.push_back(PAWI); } + // set sret param + if (f->llvmRetInPtr) + { + PAWI.Index = 1; + PAWI.Attrs = llvm::ParamAttr::StructRet; + attrs.push_back(PAWI); + } + // set byval attrs on implicit main arg if (fdecl->isMain() && Argument::dim(f->parameters) == 0) { @@ -338,9 +343,9 @@ } // set attrs on the rest of the arguments - for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k) + for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) { - Argument* fnarg = (Argument*)f->parameters->data[k]; + Argument* fnarg = Argument::getNth(f->parameters, k); assert(fnarg); PAWI.Index = llidx; @@ -428,7 +433,7 @@ assert(llvm::isa(f->ir.type->get())); // parameter attributes - if (f->parameters && !fdecl->isIntrinsic()) { + if (!fdecl->isIntrinsic()) { set_param_attrs(f, func, fdecl); } @@ -458,7 +463,7 @@ ++iarg; } if (f->llvmUsesThis) { - iarg->setName("this"); + iarg->setName(fdecl->isNested()?".context":"this"); fdecl->ir.irFunc->thisVar = iarg; assert(fdecl->ir.irFunc->thisVar); ++iarg; diff -r 60332cd85308 -r 283d113d4753 gen/tocall.cpp --- a/gen/tocall.cpp Sat Aug 02 01:23:53 2008 +0200 +++ b/gen/tocall.cpp Sat Aug 02 02:54:57 2008 +0200 @@ -213,6 +213,13 @@ LLFunctionType::param_iterator argbegin = callableTy->param_begin(); LLFunctionType::param_iterator argiter = argbegin; + // parameter attributes + llvm::PAListPtr palist; + + // return attrs + if (tf->llvmRetAttrs) + palist = palist.addAttr(0, tf->llvmRetAttrs); + // handle implicit arguments std::vector args; @@ -222,6 +229,7 @@ LLValue* retvar = new llvm::AllocaInst(argiter->get()->getContainedType(0), ".rettmp", gIR->topallocapoint()); ++argiter; args.push_back(retvar); + palist = palist.addAttr(1, llvm::ParamAttr::StructRet); } // then comes a context argument... @@ -261,10 +269,6 @@ } // handle the rest of the arguments based on param passing style - llvm::PAListPtr palist; - - if (tf->llvmRetAttrs) - palist = palist.addAttr(0, tf->llvmRetAttrs); // variadic instrinsics need some custom casts if (va_intrinsic) @@ -296,7 +300,7 @@ Argument* fnarg = Argument::getNth(tf->parameters, i); DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); LLValue* arg = argval->getRVal(); - if (fnarg) + if (fnarg) // can fnarg ever be null in this block? { if (arg->getType() != callableTy->getParamType(j)) arg = DtoBitCast(arg, callableTy->getParamType(j)); diff -r 60332cd85308 -r 283d113d4753 runtime/llvmdc.diff --- a/runtime/llvmdc.diff Sat Aug 02 01:23:53 2008 +0200 +++ b/runtime/llvmdc.diff Sat Aug 02 02:54:57 2008 +0200 @@ -94,6 +94,54 @@ version( X86_64 ) { +Index: lib/unittest.sh +=================================================================== +--- lib/unittest.sh (revision 3831) ++++ lib/unittest.sh (working copy) +@@ -18,8 +18,9 @@ + --help: This message + --run-all: Reports result instead of breaking. Do not use this if you want to + run unittest runner through a debugger. +- dmd: Builds unittests for dmd +- gdc: Builds unittests for gdc ++ dmd: Builds unittests for dmd ++ gdc: Builds unittests for gdc ++ llvmdc: Builds unittests for llvmdc + + : Builds unittests for all known compilers.' + exit 0 +@@ -125,6 +126,9 @@ + gdc) + GDC=1 + ;; ++ llvmdc) ++ LLVMDC=1 ++ ;; + *) + usage + ;; +@@ -132,10 +136,11 @@ + shift + done + +-if [ ! "$DMD" -a ! "$GDC" ] ++if [ ! "$DMD" -a ! "$GDC" -a ! "$LLVMDC" ] + then + DMD=1 + GDC=1 ++ LLVMDC=1 + fi + + if [ "$DMD" = "1" ] +@@ -146,4 +151,7 @@ + then + compile gdc runUnitTest_gdc + fi +- ++if [ "$LLVMDC" = "1" ] ++then ++ compile llvmdc runUnitTest_llvmdc ++fi Index: lib/gc/basic/gcx.d =================================================================== --- lib/gc/basic/gcx.d (revision 3831)