Mercurial > projects > ldc
diff gen/functions.cpp @ 445:cc40db549aea
Changed the handling of variadic intrinsics a bit.
Removed the -fp80 option and made real be 80bit floats on X86, this is what the D spec really says it should be and fixes a bunch of issues.
Changed the handling of parameter attributes to a bit more generalized approach.
Added sext/zext attributes for byte/short/ubyte/ushort parameters, fixes #60 .
Parameter attribs now properly set for intrinsic calls if necessary.
Made the tango.math.Math patch less intrusive.
Fixed/added some mini tests.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Fri, 01 Aug 2008 17:59:58 +0200 |
parents | 44f08170f4ef |
children | 7a67dedbf933 |
line wrap: on
line diff
--- a/gen/functions.cpp Fri Aug 01 01:12:33 2008 +0200 +++ b/gen/functions.cpp Fri Aug 01 17:59:58 2008 +0200 @@ -1,5 +1,6 @@ #include "gen/llvm.h" #include "llvm/Support/CFG.h" +#include "llvm/Intrinsics.h" #include "mtype.h" #include "aggregate.h" @@ -62,7 +63,6 @@ } else{ assert(rt); - Type* rtfin = DtoDType(rt); if (DtoIsReturnedInArg(rt)) { rettype = getPtrToType(DtoType(rt)); actualRettype = LLType::VoidTy; @@ -72,6 +72,11 @@ rettype = DtoType(rt); actualRettype = rettype; } + + if (unsigned ea = DtoShouldExtend(rt)) + { + f->llvmRetAttrs |= ea; + } } if (retinptr) { @@ -103,8 +108,6 @@ size_t n = Argument::dim(f->parameters); - int nbyval = 0; - for (int i=0; i < n; ++i) { Argument* arg = Argument::getNth(f->parameters, i); // ensure scalar @@ -117,7 +120,8 @@ if (isaStruct(at)) { Logger::println("struct param"); paramvec.push_back(getPtrToType(at)); - arg->llvmByVal = !refOrOut; + if (!refOrOut) + arg->llvmAttrs |= llvm::ParamAttr::ByVal; } else if (isaArray(at)) { // static array are passed by reference @@ -137,6 +141,10 @@ } else { Logger::println("in param"); + if (unsigned ea = DtoShouldExtend(argT)) + { + arg->llvmAttrs |= ea; + } } paramvec.push_back(at); } @@ -151,9 +159,6 @@ Logger::cout() << "lazy updated to: " << *at << '\n'; paramvec.back() = at; } - - if (arg->llvmByVal) - nbyval++; } //warning("set %d byval args for type: %s", nbyval, f->toChars()); @@ -180,27 +185,17 @@ } TypeFunction* f = (TypeFunction*)fdecl->type; - assert(f != 0); - - const llvm::PointerType* i8pty = getPtrToType(LLType::Int8Ty); - std::vector<const LLType*> args; + const llvm::FunctionType* fty = 0; - if (fdecl->llvmInternal == LLVMva_start) { - args.push_back(i8pty); - } - else if (fdecl->llvmInternal == LLVMva_intrinsic) { - size_t n = Argument::dim(f->parameters); - for (size_t i=0; i<n; ++i) { - args.push_back(i8pty); - } - } - else - assert(0); - - const llvm::FunctionType* fty = llvm::FunctionType::get(LLType::VoidTy, args, false); + if (fdecl->llvmInternal == LLVMva_start) + fty = GET_INTRINSIC_DECL(vastart)->getFunctionType(); + else if (fdecl->llvmInternal == LLVMva_copy) + fty = GET_INTRINSIC_DECL(vacopy)->getFunctionType(); + else if (fdecl->llvmInternal == LLVMva_end) + fty = GET_INTRINSIC_DECL(vaend)->getFunctionType(); + assert(fty); f->ir.type = new llvm::PATypeHolder(fty); - return fty; } @@ -208,14 +203,13 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl) { - if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { + // handle for C vararg intrinsics + if (fdecl->isVaIntrinsic()) return DtoVaFunctionType(fdecl); - } // type has already been resolved - if (fdecl->type->ir.type != 0) { + if (fdecl->type->ir.type != 0) return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get()); - } const LLType* thisty = NULL; if (fdecl->needThis()) { @@ -246,22 +240,16 @@ { TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type); const llvm::FunctionType* fty = DtoVaFunctionType(fdecl); - LLConstant* fn = 0; + llvm::Function* func = 0; - if (fdecl->llvmInternal == LLVMva_start) { - fn = gIR->module->getOrInsertFunction("llvm.va_start", fty); - assert(fn); - } - else if (fdecl->llvmInternal == LLVMva_intrinsic) { - fn = gIR->module->getOrInsertFunction(fdecl->intrinsicName, fty); - assert(fn); - } - else - assert(0); + if (fdecl->llvmInternal == LLVMva_start) + func = GET_INTRINSIC_DECL(vastart); + else if (fdecl->llvmInternal == LLVMva_copy) + func = GET_INTRINSIC_DECL(vacopy); + else if (fdecl->llvmInternal == LLVMva_end) + func = GET_INTRINSIC_DECL(vaend); + assert(func); - llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn); - assert(func); - assert(func->isIntrinsic()); fdecl->ir.irFunc->func = func; return func; } @@ -330,36 +318,43 @@ std::vector<llvm::ParamAttrsWithIndex> attrs; int k = 0; - int nbyval = 0; + llvm::ParamAttrsWithIndex PAWI; + // set zext/sext attr on return value if necessary + if (f->next->isintegral() && f->next->size() < PTRSIZE) + { + PAWI.Index = 0; + if (f->next->isunsigned()) + PAWI.Attrs = llvm::ParamAttr::ZExt; + else + PAWI.Attrs = llvm::ParamAttr::SExt; + attrs.push_back(PAWI); + } + + // set byval attrs on implicit main arg 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++; } + // set attrs on the rest of the arguments 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; + + PAWI.Index = llidx; + PAWI.Attrs = fnarg->llvmAttrs; + + if (PAWI.Attrs) attrs.push_back(PAWI); - nbyval++; - } } - if (nbyval) { - llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end()); - func->setParamAttrs(palist); - } + llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end()); + func->setParamAttrs(palist); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -412,9 +407,8 @@ mangled_name = fdecl->mangle(); llvm::Function* vafunc = 0; - if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { + if (fdecl->isVaIntrinsic()) vafunc = DtoDeclareVaFunction(fdecl); - } // construct function const llvm::FunctionType* functype = DtoFunctionType(fdecl); @@ -437,7 +431,7 @@ assert(llvm::isa<llvm::FunctionType>(f->ir.type->get())); // parameter attributes - if (f->parameters) { + if (f->parameters && !fdecl->isIntrinsic()) { set_param_attrs(f, func, fdecl); } @@ -812,3 +806,15 @@ } ////////////////////////////////////////////////////////////////////////////////////////// + +bool FuncDeclaration::isIntrinsic() +{ + return (llvmInternal == LLVMintrinsic || isVaIntrinsic()); +} + +bool FuncDeclaration::isVaIntrinsic() +{ + return (llvmInternal == LLVMva_start || + llvmInternal == LLVMva_copy || + llvmInternal == LLVMva_end); +}