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...
This commit is contained in:
Tomas Lindquist Olsen 2008-08-02 02:54:57 +02:00
parent 0251a1e720
commit 18b376ba66
3 changed files with 70 additions and 13 deletions

View file

@ -158,11 +158,10 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
at = getPtrToType(DtoType(ltd)); at = getPtrToType(DtoType(ltd));
Logger::cout() << "lazy updated to: " << *at << '\n'; Logger::cout() << "lazy updated to: " << *at << '\n';
paramvec.back() = at; 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 // construct function type
bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs;
llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); 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) static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl)
{ {
assert(f->parameters);
int llidx = 1; int llidx = 1;
if (f->llvmRetInPtr) ++llidx; if (f->llvmRetInPtr) ++llidx;
if (f->llvmUsesThis) ++llidx; if (f->llvmUsesThis) ++llidx;
@ -328,6 +325,14 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
attrs.push_back(PAWI); 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 // set byval attrs on implicit main arg
if (fdecl->isMain() && Argument::dim(f->parameters) == 0) 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 // 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); assert(fnarg);
PAWI.Index = llidx; PAWI.Index = llidx;
@ -428,7 +433,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
assert(llvm::isa<llvm::FunctionType>(f->ir.type->get())); assert(llvm::isa<llvm::FunctionType>(f->ir.type->get()));
// parameter attributes // parameter attributes
if (f->parameters && !fdecl->isIntrinsic()) { if (!fdecl->isIntrinsic()) {
set_param_attrs(f, func, fdecl); set_param_attrs(f, func, fdecl);
} }
@ -458,7 +463,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
++iarg; ++iarg;
} }
if (f->llvmUsesThis) { if (f->llvmUsesThis) {
iarg->setName("this"); iarg->setName(fdecl->isNested()?".context":"this");
fdecl->ir.irFunc->thisVar = iarg; fdecl->ir.irFunc->thisVar = iarg;
assert(fdecl->ir.irFunc->thisVar); assert(fdecl->ir.irFunc->thisVar);
++iarg; ++iarg;

View file

@ -213,6 +213,13 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
LLFunctionType::param_iterator argbegin = callableTy->param_begin(); LLFunctionType::param_iterator argbegin = callableTy->param_begin();
LLFunctionType::param_iterator argiter = argbegin; LLFunctionType::param_iterator argiter = argbegin;
// parameter attributes
llvm::PAListPtr palist;
// return attrs
if (tf->llvmRetAttrs)
palist = palist.addAttr(0, tf->llvmRetAttrs);
// handle implicit arguments // handle implicit arguments
std::vector<LLValue*> args; std::vector<LLValue*> 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()); LLValue* retvar = new llvm::AllocaInst(argiter->get()->getContainedType(0), ".rettmp", gIR->topallocapoint());
++argiter; ++argiter;
args.push_back(retvar); args.push_back(retvar);
palist = palist.addAttr(1, llvm::ParamAttr::StructRet);
} }
// then comes a context argument... // 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 // 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 // variadic instrinsics need some custom casts
if (va_intrinsic) if (va_intrinsic)
@ -296,7 +300,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
Argument* fnarg = Argument::getNth(tf->parameters, i); Argument* fnarg = Argument::getNth(tf->parameters, i);
DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
LLValue* arg = argval->getRVal(); LLValue* arg = argval->getRVal();
if (fnarg) if (fnarg) // can fnarg ever be null in this block?
{ {
if (arg->getType() != callableTy->getParamType(j)) if (arg->getType() != callableTy->getParamType(j))
arg = DtoBitCast(arg, callableTy->getParamType(j)); arg = DtoBitCast(arg, callableTy->getParamType(j));

View file

@ -94,6 +94,54 @@ Index: lib/common/tango/core/Thread.d
version( X86_64 ) 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
<none>: 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 Index: lib/gc/basic/gcx.d
=================================================================== ===================================================================
--- lib/gc/basic/gcx.d (revision 3831) --- lib/gc/basic/gcx.d (revision 3831)