aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/RegisterScavenging.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2021-11-30 21:26:08 -0500
committerMatt Arsenault <Matthew.Arsenault@amd.com>2022-01-12 18:56:52 -0500
commit5f39a02ea950dbbc146f2e22a7a51e5dea430ce6 (patch)
tree5a83ed75ddabf16c9e0331c61927d6f141391a7d /llvm/lib/CodeGen/RegisterScavenging.cpp
parent4515c24bbc32196957b03c6a42259d460c9c4848 (diff)
downloadllvm-5f39a02ea950dbbc146f2e22a7a51e5dea430ce6.zip
llvm-5f39a02ea950dbbc146f2e22a7a51e5dea430ce6.tar.gz
llvm-5f39a02ea950dbbc146f2e22a7a51e5dea430ce6.tar.bz2
RegScavenger: Remove used regs from scavenge candidates
In a future change, AMDGPU will have 2 emergency scavenging indexes in some situations. The secondary scavenging index ends up being used recursively when the scavenger calls eliminateFrameIndex for the emergency spill slot. Without this, it would end up seeing the same register which was just scavenged in the parent call as free, inserts a second emergency spill to the same location and returns the same register when 2 unique free registers are required. We need to only do this if the register is used. SystemZ uses 2 scavenging slots, but calls the scavenger twice in sequence and not recursively. In this case the previously scavenged register can be re-clobbered, but is still tracked in the scavenger until it sees the deferred restore instruction.
Diffstat (limited to 'llvm/lib/CodeGen/RegisterScavenging.cpp')
-rw-r--r--llvm/lib/CodeGen/RegisterScavenging.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/RegisterScavenging.cpp b/llvm/lib/CodeGen/RegisterScavenging.cpp
index c0a07ec..424ad74 100644
--- a/llvm/lib/CodeGen/RegisterScavenging.cpp
+++ b/llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -533,6 +533,22 @@ Register RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
Candidates.reset(*AI);
}
+ // If we have already scavenged some registers, remove them from the
+ // candidates. If we end up recursively calling eliminateFrameIndex, we don't
+ // want to be clobbering previously scavenged registers or their associated
+ // stack slots.
+ for (ScavengedInfo &SI : Scavenged) {
+ if (SI.Reg) {
+ if (isRegUsed(SI.Reg)) {
+ LLVM_DEBUG(
+ dbgs() << "Removing " << printReg(SI.Reg, TRI) <<
+ " from scavenging candidates since it was already scavenged\n");
+ for (MCRegAliasIterator AI(SI.Reg, TRI, true); AI.isValid(); ++AI)
+ Candidates.reset(*AI);
+ }
+ }
+ }
+
// Try to find a register that's unused if there is one, as then we won't
// have to spill.
BitVector Available = getRegsAvailable(RC);
@@ -553,6 +569,12 @@ Register RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
if (!AllowSpill)
return 0;
+#ifndef NDEBUG
+ for (ScavengedInfo &SI : Scavenged) {
+ assert(SI.Reg != SReg && "scavenged a previously scavenged register");
+ }
+#endif
+
ScavengedInfo &Scavenged = spill(SReg, *RC, SPAdj, I, UseMI);
Scavenged.Restore = &*std::prev(UseMI);