Mercurial > projects > ldc
diff gen/functions.cpp @ 217:0806379a5eca trunk
[svn r233] Added: -oq command line option for writing fully qualified object names.
Added: started support for x86 80bit floating point.
Changed: aggregates passed by value now use the llvm 'byval' parameter attribute, also lays ground work for
using other attributes.
Changed: eliminated a lot more std::vectorS, these showed up pretty much at the top when profiling!
Changed: performed other misc. cleanups.
Changed: halt expression now call the new llvm trap intrinsic instead of an assert(0).
Changed: dstress suite now passes -O0 by default, this only eliminates unreferenced globals, which speeds up
linking quite a bit.
author | lindquist |
---|---|
date | Thu, 05 Jun 2008 06:38:36 +0200 |
parents | a58d8f4b84df |
children | 74701ba40398 |
line wrap: on
line diff
--- a/gen/functions.cpp Tue Jun 03 22:32:59 2008 +0200 +++ b/gen/functions.cpp Thu Jun 05 06:38:36 2008 +0200 @@ -51,7 +51,7 @@ else { assert(rt); Type* rtfin = DtoDType(rt); - if (DtoIsPassedByRef(rt)) { + if (DtoIsReturnedInArg(rt)) { rettype = getPtrToType(DtoType(rt)); actualRettype = llvm::Type::VoidTy; f->llvmRetInPtr = retinptr = true; @@ -94,22 +94,30 @@ size_t n = Argument::dim(f->parameters); + int nbyval = 0; + + llvm::PAListPtr palist; + for (int i=0; i < n; ++i) { Argument* arg = Argument::getNth(f->parameters, i); // ensure scalar Type* argT = DtoDType(arg->type); assert(argT); + bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); + const LLType* at = DtoType(argT); if (isaStruct(at)) { Logger::println("struct param"); paramvec.push_back(getPtrToType(at)); + arg->llvmByVal = !refOrOut; } else if (isaArray(at)) { Logger::println("sarray param"); assert(argT->ty == Tsarray); //paramvec.push_back(getPtrToType(at->getContainedType(0))); paramvec.push_back(getPtrToType(at)); + arg->llvmByVal = !refOrOut; } else if (llvm::isa<llvm::OpaqueType>(at)) { Logger::println("opaque param"); @@ -117,7 +125,7 @@ paramvec.push_back(getPtrToType(at)); } else { - if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) { + if (refOrOut) { Logger::println("by ref param"); at = getPtrToType(at); } @@ -126,8 +134,13 @@ } paramvec.push_back(at); } + + if (arg->llvmByVal) + nbyval++; } + //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); @@ -135,10 +148,7 @@ f->llvmRetInPtr = retinptr; f->llvmUsesThis = usesthis; - //if (!f->ir.type) - f->ir.type = new llvm::PATypeHolder(functype); - //else - //assert(functype == f->ir.type->get()); + f->ir.type = new llvm::PATypeHolder(functype); return functype; } @@ -378,6 +388,43 @@ fdecl->ir.irFunc->func = func; assert(llvm::isa<llvm::FunctionType>(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<llvm::ParamAttrsWithIndex> attrs; + int k = 0; + + int nbyval = 0; + + 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); + } + } + // main if (fdecl->isMain()) { gIR->mainFunc = func; @@ -775,19 +822,14 @@ else arg = new DImValue(argexp->type, arg->getRVal(), false); } - // aggregate arg - else if (DtoIsPassedByRef(argexp->type)) + // byval arg, but expr has no storage yet + else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isComplex() || arg->isNull())) { LLValue* alloc = new llvm::AllocaInst(DtoType(argexp->type), "tmpparam", gIR->topallocapoint()); DVarValue* vv = new DVarValue(argexp->type, alloc, true); DtoAssign(vv, arg); arg = vv; } - // normal arg (basic/value type) - else - { - // nothing to do - } return arg; }