mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-15 20:33:14 +01:00
Convert struct arg to integer when passing inreg to make sure LLVM doesn't
ignore the attribute!
This commit is contained in:
@@ -2691,7 +2691,7 @@ TypeFunction::TypeFunction(Arguments *parameters, Type *treturn, int varargs, en
|
||||
this->retInPtr = false;
|
||||
this->usesThis = false;
|
||||
this->usesNest = false;
|
||||
this->structInregArg = false;
|
||||
this->structInregArg = NULL;
|
||||
this->retAttrs = 0;
|
||||
this->thisAttrs = 0;
|
||||
this->reverseParams = false;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
// llvm
|
||||
#include "../ir/irtype.h"
|
||||
namespace llvm { class Type; }
|
||||
|
||||
struct Scope;
|
||||
struct Identifier;
|
||||
@@ -438,7 +439,8 @@ struct TypeFunction : Type
|
||||
bool retInPtr;
|
||||
bool usesThis;
|
||||
bool usesNest;
|
||||
bool structInregArg;
|
||||
// when the last arg is a struct and passed in EAX, this holds its real type
|
||||
const llvm::Type* structInregArg;
|
||||
unsigned retAttrs;
|
||||
unsigned thisAttrs; // also used for nest
|
||||
// parameter index in the llvm function that contains the first not-implicit arg
|
||||
|
||||
@@ -220,15 +220,15 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, co
|
||||
arg->llvmAttrs |= llvm::Attribute::InReg;
|
||||
assert((f->thisAttrs & llvm::Attribute::InReg) == 0 && "can't have two inreg args!");
|
||||
|
||||
// structs need to go from {...}* byval to {...} inreg
|
||||
// structs need to go from {...}* byval to i8/i16/i32 inreg
|
||||
if ((arg->storageClass & STCin) && t->ty == Tstruct)
|
||||
{
|
||||
int n_param = f->reverseParams ? f->firstRealArg + n - 1 - n_inreg : f->firstRealArg + n_inreg;
|
||||
assert(isaPointer(paramvec[n_param]) && (arg->llvmAttrs & llvm::Attribute::ByVal)
|
||||
&& "struct parameter expected to be {...}* byval before inreg is applied");
|
||||
paramvec[n_param] = paramvec[n_param]->getContainedType(0);
|
||||
f->structInregArg = paramvec[n_param]->getContainedType(0);
|
||||
paramvec[n_param] = LLIntegerType::get(8*t->size());
|
||||
arg->llvmAttrs &= ~llvm::Attribute::ByVal;
|
||||
f->structInregArg = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,11 +759,14 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||
if (f->structInregArg && i == (f->reverseParams ? n - 1 : 0))
|
||||
{
|
||||
int n_param = f->reverseParams ? f->firstRealArg + n - 1 - i : f->firstRealArg + i;
|
||||
assert(!f->usesNest && !f->usesThis && isaStruct(functype->getParamType(n_param))
|
||||
const LLType* paramty = functype->getParamType(n_param);
|
||||
assert(!f->usesNest && !f->usesThis &&
|
||||
llvm::isa<LLIntegerType>(paramty) && isaStruct(f->structInregArg)
|
||||
&& "Preconditions for inreg struct arg not met!");
|
||||
|
||||
LLValue* mem = DtoAlloca(functype->getParamType(n_param), "inregstructarg");
|
||||
DtoStore(irloc->value, mem);
|
||||
LLValue* mem = DtoAlloca(f->structInregArg, "inregstructarg");
|
||||
|
||||
DtoStore(irloc->value, DtoBitCast(mem, getPtrToType(paramty)));
|
||||
irloc->value = mem;
|
||||
}
|
||||
|
||||
|
||||
@@ -370,15 +370,16 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
||||
DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
|
||||
LLValue* arg = argval->getRVal();
|
||||
|
||||
int j = tf->reverseParams ? beg + n - i - 1 : beg + i;
|
||||
|
||||
// if it's a struct inreg arg, load first to pass as first-class value
|
||||
if (tf->structInregArg && i == (tf->reverseParams ? n - 1 : 0))
|
||||
{
|
||||
assert(fnarg->llvmAttrs & llvm::Attribute::InReg);
|
||||
assert((fnarg->llvmAttrs & llvm::Attribute::InReg) && isaStruct(tf->structInregArg));
|
||||
arg = DtoBitCast(arg, getPtrToType(callableTy->getParamType(j)));
|
||||
arg = DtoLoad(arg);
|
||||
}
|
||||
|
||||
int j = tf->reverseParams ? beg + n - i - 1 : beg + i;
|
||||
|
||||
// parameter type mismatch, this is hard to get rid of
|
||||
if (arg->getType() != callableTy->getParamType(j))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user