diff options
author | Hyeongseok Oh <hseok82.oh@samsung.com> | 2017-06-29 03:01:18 +0900 |
---|---|---|
committer | Bruce Forstall <brucefo@microsoft.com> | 2017-06-28 11:01:18 -0700 |
commit | 0ce4fab8647ac3fbc200c27adfcf31aaae0f660b (patch) | |
tree | 18e3162db4f7b757906c20d006286b2094f923fa /src/jit/regset.cpp | |
parent | 217ab30d021f27be6fe4f35126a88e592366acbf (diff) | |
download | coreclr-0ce4fab8647ac3fbc200c27adfcf31aaae0f660b.tar.gz coreclr-0ce4fab8647ac3fbc200c27adfcf31aaae0f660b.tar.bz2 coreclr-0ce4fab8647ac3fbc200c27adfcf31aaae0f660b.zip |
[RyuJIT/ARM32] Enable passing large split struct argument (#12050)
* [RyuJIT/ARM32] Enable passing large split struct
This enables passing split struct larger than 16 bytes.
To support splitted struct, it defines new GenTree type - GenTreePutArgSplit.
GenTreePutArgSplit is similar with GenTreePutArgStk,
but it is used for splitted struct only
and it has additional field to save register information.
GenTreePutArgSplit node is generated in lower phase.
* Apply reviews: split struct argument passing
- Fix some comments:
genPutArgSplit, GenTreePutArgStk, GenTreePutArgSplit, NuwPutArg, ArgComplete
- Add assertion check in genPutArgSplit, genCallInstruction
- Rename variable: baseReg
- Change flag for GenTreePutArgSplit: _TARGET_ARM && !LEGACY_BACKEND
- Change type of gtOtherRegs in GenTreePutArgSplit
- Remove duplicated code: NewPutArg
- Implement spill & restore flag for GenTreePutArgSplit
* Apply reviews
- Rebase
- Update managing spillFlag for split struct
- Implement spill & restore code generation
- Fix typos and rename variables
- Fix bug related to print gentree for split struct
* Fix bug and comments
- Fix bug in regset.cpp
- Add comments in morph.cpp's NYI_ARM
- Fix comments' typo in lsraarmarcp.cpp
Diffstat (limited to 'src/jit/regset.cpp')
-rw-r--r-- | src/jit/regset.cpp | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/src/jit/regset.cpp b/src/jit/regset.cpp index 48ec6ea6f1..720466348c 100644 --- a/src/jit/regset.cpp +++ b/src/jit/regset.cpp @@ -1527,6 +1527,9 @@ void RegSet::rsSpillTree(regNumber reg, GenTreePtr tree, unsigned regIdx /* =0 * GenTreeCall* call = nullptr; var_types treeType; +#if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_) + GenTreePutArgSplit* splitArg = nullptr; +#endif #ifndef LEGACY_BACKEND if (tree->IsMultiRegCall()) @@ -1535,8 +1538,15 @@ void RegSet::rsSpillTree(regNumber reg, GenTreePtr tree, unsigned regIdx /* =0 * ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc(); treeType = retTypeDesc->GetReturnRegType(regIdx); } +#ifdef _TARGET_ARM_ + else if (tree->OperIsPutArgSplit()) + { + splitArg = tree->AsPutArgSplit(); + treeType = splitArg->GetRegType(regIdx); + } +#endif // _TARGET_ARM_ else -#endif +#endif // !LEGACY_BACKEND { treeType = tree->TypeGet(); } @@ -1584,6 +1594,14 @@ void RegSet::rsSpillTree(regNumber reg, GenTreePtr tree, unsigned regIdx /* =0 * assert((regFlags & GTF_SPILL) != 0); regFlags &= ~GTF_SPILL; } +#ifdef _TARGET_ARM_ + else if (splitArg != nullptr) + { + regFlags = splitArg->GetRegSpillFlagByIdx(regIdx); + assert((regFlags & GTF_SPILL) != 0); + regFlags &= ~GTF_SPILL; + } +#endif // _TARGET_ARM_ else { assert(!varTypeIsMultiReg(tree)); @@ -1603,9 +1621,12 @@ void RegSet::rsSpillTree(regNumber reg, GenTreePtr tree, unsigned regIdx /* =0 * assert(tree->InReg()); assert(tree->gtRegNum == reg); } +#elif defined(_TARGET_ARM_) + assert(tree->gtRegNum == reg || (call != nullptr && call->GetRegNumByIdx(regIdx) == reg) || + (splitArg != nullptr && splitArg->GetRegNumByIdx(regIdx) == reg)); #else assert(tree->gtRegNum == reg || (call != nullptr && call->GetRegNumByIdx(regIdx) == reg)); -#endif // CPU_LONG_USES_REGPAIR +#endif // !CPU_LONG_USES_REGPAIR && !_TARGET_ARM_ // Are any registers free for spillage? SpillDsc* spill = SpillDsc::alloc(m_rsCompiler, this, tempType); @@ -1726,6 +1747,13 @@ void RegSet::rsSpillTree(regNumber reg, GenTreePtr tree, unsigned regIdx /* =0 * regFlags |= GTF_SPILLED; call->SetRegSpillFlagByIdx(regFlags, regIdx); } +#ifdef _TARGET_ARM_ + else if (splitArg != nullptr) + { + regFlags |= GTF_SPILLED; + splitArg->SetRegSpillFlagByIdx(regFlags, regIdx); + } +#endif // _TARGET_ARM_ #endif //! LEGACY_BACKEND } @@ -2355,6 +2383,15 @@ TempDsc* RegSet::rsUnspillInPlace(GenTreePtr tree, regNumber oldReg, unsigned re flags &= ~GTF_SPILLED; call->SetRegSpillFlagByIdx(flags, regIdx); } +#if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_) + else if (tree->OperIsPutArgSplit()) + { + GenTreePutArgSplit* splitArg = tree->AsPutArgSplit(); + unsigned flags = splitArg->GetRegSpillFlagByIdx(regIdx); + flags &= ~GTF_SPILLED; + splitArg->SetRegSpillFlagByIdx(flags, regIdx); + } +#endif // !LEGACY_BACKEND && _TARGET_ARM_ else { tree->gtFlags &= ~GTF_SPILLED; |