mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-08 03:46:02 +03:00
Added inreg attribute where appropriate on x86 to follow ABI docs.
Removed now unnecessary temporary variable in StringExp.
This commit is contained in:
parent
a52f0330d0
commit
f71b7ac284
5 changed files with 51 additions and 3 deletions
|
@ -2672,6 +2672,7 @@ TypeFunction::TypeFunction(Arguments *parameters, Type *treturn, int varargs, en
|
|||
this->usesThis = false;
|
||||
this->usesNest = false;
|
||||
this->retAttrs = 0;
|
||||
this->thisAttrs = 0;
|
||||
}
|
||||
|
||||
Type *TypeFunction::syntaxCopy()
|
||||
|
@ -2683,6 +2684,7 @@ Type *TypeFunction::syntaxCopy()
|
|||
t->usesThis = usesThis;
|
||||
t->usesNest = usesNest;
|
||||
t->retAttrs = retAttrs;
|
||||
t->thisAttrs = thisAttrs;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
@ -439,6 +439,7 @@ struct TypeFunction : Type
|
|||
bool usesThis;
|
||||
bool usesNest;
|
||||
unsigned retAttrs;
|
||||
unsigned thisAttrs; // also used for nest
|
||||
};
|
||||
|
||||
struct TypeDelegate : Type
|
||||
|
|
|
@ -171,6 +171,39 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, co
|
|||
bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs;
|
||||
llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
|
||||
|
||||
// tell first param to be passed in a register if we can
|
||||
// ONLY extern(D) functions !
|
||||
if ((n > 0 || usesthis || usesnest) && f->linkage == LINKd)
|
||||
{
|
||||
// FIXME: Only x86 right now ...
|
||||
if (global.params.cpu == ARCHx86)
|
||||
{
|
||||
// pass first param in EAX if it fits, is not floating point and is not a 3 byte struct.
|
||||
// FIXME: struct are not passed in EAX yet
|
||||
|
||||
// if there is a implicit context parameter, pass it in EAX
|
||||
if (usesthis || usesnest)
|
||||
{
|
||||
f->thisAttrs |= llvm::Attribute::InReg;
|
||||
}
|
||||
// otherwise check the first formal parameter
|
||||
else
|
||||
{
|
||||
Argument* arg = Argument::getNth(f->parameters, 0);
|
||||
Type* t = arg->type->toBasetype();
|
||||
|
||||
// 32bit ints, pointers, classes and static arrays are candidate for being passed in EAX
|
||||
if ((arg->storageClass & STCin) &&
|
||||
((t->isscalar() && !t->isfloating()) || t->ty == Tclass || t->ty == Tsarray) &&
|
||||
(t->size() <= PTRSIZE))
|
||||
{
|
||||
arg->llvmAttrs |= llvm::Attribute::InReg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
f->retInPtr = retinptr;
|
||||
f->usesThis = usesthis;
|
||||
f->usesNest = usesnest;
|
||||
|
@ -350,6 +383,14 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
|
|||
attrs.push_back(PAWI);
|
||||
}
|
||||
|
||||
// set this/nest param attrs
|
||||
if (f->thisAttrs)
|
||||
{
|
||||
PAWI.Index = f->retInPtr ? 2 : 1;
|
||||
PAWI.Attrs = f->thisAttrs;
|
||||
attrs.push_back(PAWI);
|
||||
}
|
||||
|
||||
// set attrs on the rest of the arguments
|
||||
for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k)
|
||||
{
|
||||
|
|
|
@ -257,6 +257,8 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
LLValue* retvar = DtoAlloca(argiter->get()->getContainedType(0), ".rettmp");
|
||||
++argiter;
|
||||
args.push_back(retvar);
|
||||
|
||||
// add attrs for hidden ptr
|
||||
palist = palist.addAttr(1, llvm::Attribute::StructRet);
|
||||
}
|
||||
|
||||
|
@ -299,6 +301,10 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
error(loc, "Context argument required but none given");
|
||||
fatal();
|
||||
}
|
||||
|
||||
// add attributes for context argument
|
||||
if (tf->thisAttrs)
|
||||
palist = palist.addAttr(retinptr?2:1, tf->thisAttrs);
|
||||
}
|
||||
|
||||
// handle the rest of the arguments based on param passing style
|
||||
|
|
|
@ -373,9 +373,7 @@ DValue* StringExp::toElem(IRState* p)
|
|||
|
||||
if (dtype->ty == Tarray) {
|
||||
LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false);
|
||||
LLValue* tmpmem = DtoAlloca(DtoType(dtype),"tempstring");
|
||||
DtoSetArray(tmpmem, clen, arrptr);
|
||||
return new DVarValue(type, tmpmem);
|
||||
return new DImValue(type, DtoConstSlice(clen, arrptr));
|
||||
}
|
||||
else if (dtype->ty == Tsarray) {
|
||||
const LLType* dstType = getPtrToType(LLArrayType::get(ct, len));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue