[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.
This commit is contained in:
Tomas Lindquist Olsen
2008-06-05 06:38:36 +02:00
parent 1a41b9ef12
commit d03c3a7757
23 changed files with 299 additions and 187 deletions

View File

@@ -51,7 +51,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
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 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
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 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
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 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
}
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 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
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 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
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 @@ DValue* DtoArgument(Argument* fnarg, Expression* argexp)
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;
}