Mercurial > projects > ldc
changeset 939:cac9895be400
Automated merge with http://hg.dsource.org/projects/ldc
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Wed, 04 Feb 2009 18:39:39 +0100 |
parents | 6c09179ebba0 (current diff) a904cc9bc064 (diff) |
children | 39519a1ff603 |
files | gen/functions.cpp gen/tocall.cpp |
diffstat | 4 files changed, 17 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/dmd/mtype.c Wed Feb 04 16:02:05 2009 +0100 +++ b/dmd/mtype.c Wed Feb 04 18:39:39 2009 +0100 @@ -2691,7 +2691,7 @@ this->retInPtr = false; this->usesThis = false; this->usesNest = false; - this->structInregArg = false; + this->structInregArg = NULL; this->retAttrs = 0; this->thisAttrs = 0; this->reverseParams = false;
--- a/dmd/mtype.h Wed Feb 04 16:02:05 2009 +0100 +++ b/dmd/mtype.h Wed Feb 04 18:39:39 2009 +0100 @@ -23,6 +23,7 @@ // llvm #include "../ir/irtype.h" +namespace llvm { class Type; } struct Scope; struct Identifier; @@ -438,7 +439,8 @@ 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
--- a/gen/functions.cpp Wed Feb 04 16:02:05 2009 +0100 +++ b/gen/functions.cpp Wed Feb 04 18:39:39 2009 +0100 @@ -220,15 +220,15 @@ 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; } } } @@ -763,11 +763,14 @@ 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; }
--- a/gen/tocall.cpp Wed Feb 04 16:02:05 2009 +0100 +++ b/gen/tocall.cpp Wed Feb 04 18:39:39 2009 +0100 @@ -373,15 +373,16 @@ 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)) {