summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CallingConvLower.cpp
diff options
context:
space:
mode:
authorDavid Sherwood <david.sherwood@arm.com>2020-10-22 09:37:33 +0100
committerDavid Sherwood <david.sherwood@arm.com>2020-11-12 08:41:50 +0000
commit3225fcf11eb7741d4f0b7e891685d7133aae5c7b (patch)
tree6c82ba1610053fdf97ba75c38b537c365f2f8bb5 /llvm/lib/CodeGen/CallingConvLower.cpp
parent1551d8dd4839a12290520031bfdb401f14912457 (diff)
[SVE] Deal with SVE tuple call arguments correctly when running out of registers
When passing SVE types as arguments to function calls we can run out of hardware SVE registers. This is normally fine, since we switch to an indirect mode where we pass a pointer to a SVE stack object in a GPR. However, if we switch over part-way through processing a SVE tuple then part of it will be in registers and the other part will be on the stack. I've fixed this by ensuring that: 1. When we don't have enough registers to allocate the whole block we mark any remaining SVE registers temporarily as allocated. 2. We temporarily remove the InConsecutiveRegs flags from the last tuple part argument and reinvoke the autogenerated calling convention handler. Doing this prevents the code from entering an infinite recursion and, in combination with 1), ensures we switch over to the Indirect mode. 3. After allocating a GPR register for the pointer to the tuple we then deallocate any SVE registers we marked as allocated in 1). We also set the InConsecutiveRegs flags back how they were before. 4. I've changed the AArch64ISelLowering LowerCALL and LowerFormalArguments functions to detect the start of a tuple, which involves allocating a single stack object and doing the correct numbers of legal loads and stores. Differential Revision: https://reviews.llvm.org/D90219
Diffstat (limited to 'llvm/lib/CodeGen/CallingConvLower.cpp')
-rw-r--r--llvm/lib/CodeGen/CallingConvLower.cpp5
1 files changed, 5 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/CallingConvLower.cpp b/llvm/lib/CodeGen/CallingConvLower.cpp
index 9afaf95b5bb8..c9246f6e8754 100644
--- a/llvm/lib/CodeGen/CallingConvLower.cpp
+++ b/llvm/lib/CodeGen/CallingConvLower.cpp
@@ -63,6 +63,11 @@ void CCState::MarkAllocated(MCPhysReg Reg) {
UsedRegs[*AI / 32] |= 1 << (*AI & 31);
}
+void CCState::MarkUnallocated(MCPhysReg Reg) {
+ for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
+ UsedRegs[*AI / 32] &= ~(1 << (*AI & 31));
+}
+
bool CCState::IsShadowAllocatedReg(MCRegister Reg) const {
if (!isAllocated(Reg))
return false;