summaryrefslogtreecommitdiff
path: root/src/jit/regset.cpp
diff options
context:
space:
mode:
authorHyeongseok Oh <hseok82.oh@samsung.com>2017-06-29 03:01:18 +0900
committerBruce Forstall <brucefo@microsoft.com>2017-06-28 11:01:18 -0700
commit0ce4fab8647ac3fbc200c27adfcf31aaae0f660b (patch)
tree18e3162db4f7b757906c20d006286b2094f923fa /src/jit/regset.cpp
parent217ab30d021f27be6fe4f35126a88e592366acbf (diff)
downloadcoreclr-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.cpp41
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;