From 18b376ba66d7fbeb7d44d5ec1d2112f4d9e79ca0 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Sat, 2 Aug 2008 02:54:57 +0200 Subject: [PATCH] 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... --- gen/functions.cpp | 21 ++++++++++++-------- gen/tocall.cpp | 14 ++++++++----- runtime/llvmdc.diff | 48 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 13 deletions(-) diff --git a/gen/functions.cpp b/gen/functions.cpp index 58dabe36..9a4dc539 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -158,11 +158,10 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo 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 @@ void DtoResolveFunction(FuncDeclaration* fdecl) 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 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati 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 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati } // 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 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) 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 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) ++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 --git a/gen/tocall.cpp b/gen/tocall.cpp index f47e8f64..82db954c 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -213,6 +213,13 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* 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 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* 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 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* } // 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 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* 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 --git a/runtime/llvmdc.diff b/runtime/llvmdc.diff index c5670a1f..ef1e51b5 100644 --- a/runtime/llvmdc.diff +++ b/runtime/llvmdc.diff @@ -94,6 +94,54 @@ Index: lib/common/tango/core/Thread.d 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)