Changeset 938:a904cc9bc064
- Timestamp:
- 02/04/09 12:39:33
(3 years ago)
- Author:
- Christian Kamm <kamm incasoftware de>
- branch:
- default
- Message:
Convert struct arg to integer when passing inreg to make sure LLVM doesn't
ignore the attribute!
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r930 |
r938 |
|
| 2692 | 2692 | this->usesThis = false; |
|---|
| 2693 | 2693 | this->usesNest = false; |
|---|
| 2694 | | this->structInregArg = false; |
|---|
| | 2694 | this->structInregArg = NULL; |
|---|
| 2695 | 2695 | this->retAttrs = 0; |
|---|
| 2696 | 2696 | this->thisAttrs = 0; |
|---|
| r930 |
r938 |
|
| 24 | 24 | // llvm |
|---|
| 25 | 25 | #include "../ir/irtype.h" |
|---|
| | 26 | namespace llvm { class Type; } |
|---|
| 26 | 27 | |
|---|
| 27 | 28 | struct Scope; |
|---|
| … | … | |
| 439 | 440 | bool usesThis; |
|---|
| 440 | 441 | bool usesNest; |
|---|
| 441 | | bool structInregArg; |
|---|
| | 442 | // when the last arg is a struct and passed in EAX, this holds its real type |
|---|
| | 443 | const llvm::Type* structInregArg; |
|---|
| 442 | 444 | unsigned retAttrs; |
|---|
| 443 | 445 | unsigned thisAttrs; // also used for nest |
|---|
| r930 |
r938 |
|
| 221 | 221 | assert((f->thisAttrs & llvm::Attribute::InReg) == 0 && "can't have two inreg args!"); |
|---|
| 222 | 222 | |
|---|
| 223 | | // structs need to go from {...}* byval to {...} inreg |
|---|
| | 223 | // structs need to go from {...}* byval to i8/i16/i32 inreg |
|---|
| 224 | 224 | if ((arg->storageClass & STCin) && t->ty == Tstruct) |
|---|
| 225 | 225 | { |
|---|
| … | … | |
| 227 | 227 | assert(isaPointer(paramvec[n_param]) && (arg->llvmAttrs & llvm::Attribute::ByVal) |
|---|
| 228 | 228 | && "struct parameter expected to be {...}* byval before inreg is applied"); |
|---|
| 229 | | paramvec[n_param] = paramvec[n_param]->getContainedType(0); |
|---|
| | 229 | f->structInregArg = paramvec[n_param]->getContainedType(0); |
|---|
| | 230 | paramvec[n_param] = LLIntegerType::get(8*t->size()); |
|---|
| 230 | 231 | arg->llvmAttrs &= ~llvm::Attribute::ByVal; |
|---|
| 231 | | f->structInregArg = true; |
|---|
| 232 | 232 | } |
|---|
| 233 | 233 | } |
|---|
| … | … | |
| 760 | 760 | { |
|---|
| 761 | 761 | int n_param = f->reverseParams ? f->firstRealArg + n - 1 - i : f->firstRealArg + i; |
|---|
| 762 | | assert(!f->usesNest && !f->usesThis && isaStruct(functype->getParamType(n_param)) |
|---|
| | 762 | const LLType* paramty = functype->getParamType(n_param); |
|---|
| | 763 | assert(!f->usesNest && !f->usesThis && |
|---|
| | 764 | llvm::isa<LLIntegerType>(paramty) && isaStruct(f->structInregArg) |
|---|
| 763 | 765 | && "Preconditions for inreg struct arg not met!"); |
|---|
| 764 | 766 | |
|---|
| 765 | | LLValue* mem = DtoAlloca(functype->getParamType(n_param), "inregstructarg"); |
|---|
| 766 | | DtoStore(irloc->value, mem); |
|---|
| | 767 | LLValue* mem = DtoAlloca(f->structInregArg, "inregstructarg"); |
|---|
| | 768 | |
|---|
| | 769 | DtoStore(irloc->value, DtoBitCast(mem, getPtrToType(paramty))); |
|---|
| 767 | 770 | irloc->value = mem; |
|---|
| 768 | 771 | } |
|---|
| r930 |
r938 |
|
| 371 | 371 | LLValue* arg = argval->getRVal(); |
|---|
| 372 | 372 | |
|---|
| | 373 | int j = tf->reverseParams ? beg + n - i - 1 : beg + i; |
|---|
| | 374 | |
|---|
| 373 | 375 | // if it's a struct inreg arg, load first to pass as first-class value |
|---|
| 374 | 376 | if (tf->structInregArg && i == (tf->reverseParams ? n - 1 : 0)) |
|---|
| 375 | 377 | { |
|---|
| 376 | | assert(fnarg->llvmAttrs & llvm::Attribute::InReg); |
|---|
| | 378 | assert((fnarg->llvmAttrs & llvm::Attribute::InReg) && isaStruct(tf->structInregArg)); |
|---|
| | 379 | arg = DtoBitCast(arg, getPtrToType(callableTy->getParamType(j))); |
|---|
| 377 | 380 | arg = DtoLoad(arg); |
|---|
| 378 | 381 | } |
|---|
| 379 | | |
|---|
| 380 | | int j = tf->reverseParams ? beg + n - i - 1 : beg + i; |
|---|
| 381 | 382 | |
|---|
| 382 | 383 | // parameter type mismatch, this is hard to get rid of |
|---|