aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/RegAllocBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/RegAllocBase.cpp')
-rw-r--r--llvm/lib/CodeGen/RegAllocBase.cpp66
1 files changed, 21 insertions, 45 deletions
diff --git a/llvm/lib/CodeGen/RegAllocBase.cpp b/llvm/lib/CodeGen/RegAllocBase.cpp
index d66d396..b9599e7 100644
--- a/llvm/lib/CodeGen/RegAllocBase.cpp
+++ b/llvm/lib/CodeGen/RegAllocBase.cpp
@@ -128,8 +128,7 @@ void RegAllocBase::allocatePhysRegs() {
AvailablePhysReg = getErrorAssignment(*RC, MI);
// Keep going after reporting the error.
- VRM->assignVirt2Phys(VirtReg->reg(), AvailablePhysReg);
- FailedVRegs.insert(VirtReg->reg());
+ cleanupFailedVReg(VirtReg->reg(), AvailablePhysReg, SplitVRegs);
} else if (AvailablePhysReg)
Matrix->assign(*VirtReg, AvailablePhysReg);
@@ -163,58 +162,35 @@ void RegAllocBase::postOptimization() {
DeadRemats.clear();
}
-void RegAllocBase::cleanupFailedVRegs() {
- SmallSet<Register, 8> JunkRegs;
-
- for (Register FailedReg : FailedVRegs) {
- JunkRegs.insert(FailedReg);
-
- MCRegister PhysReg = VRM->getPhys(FailedReg);
- LiveInterval &FailedInterval = LIS->getInterval(FailedReg);
-
- // The liveness information for the failed register and anything interfering
- // with the physical register we arbitrarily chose is junk and needs to be
- // deleted.
- for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
- LiveIntervalUnion::Query &Q = Matrix->query(FailedInterval, *Units);
- for (const LiveInterval *InterferingReg : Q.interferingVRegs())
- JunkRegs.insert(InterferingReg->reg());
- LIS->removeRegUnit(*Units);
- }
+void RegAllocBase::cleanupFailedVReg(Register FailedReg, MCRegister PhysReg,
+ SmallVectorImpl<Register> &SplitRegs) {
+ // We still should produce valid IR. Kill all the uses and reduce the live
+ // ranges so that we don't think it's possible to introduce kill flags later
+ // which will fail the verifier.
+ for (MachineOperand &MO : MRI->reg_operands(FailedReg)) {
+ if (MO.readsReg())
+ MO.setIsUndef(true);
}
- for (Register JunkReg : JunkRegs) {
- MCRegister PhysReg = VRM->getPhys(JunkReg);
- // We still should produce valid IR. Kill all the uses and reduce the live
- // ranges so that we don't think it's possible to introduce kill flags
- // later which will fail the verifier.
- for (MachineOperand &MO : MRI->reg_operands(JunkReg)) {
- if (MO.readsReg())
- MO.setIsUndef(true);
- }
-
- // The liveness of the assigned physical register is also now unreliable.
+ if (!MRI->isReserved(PhysReg)) {
+ // Physical liveness for any aliasing registers is now unreliable, so delete
+ // the uses.
for (MCRegAliasIterator Aliases(PhysReg, TRI, true); Aliases.isValid();
++Aliases) {
for (MachineOperand &MO : MRI->reg_operands(*Aliases)) {
- if (MO.readsReg())
+ if (MO.readsReg()) {
MO.setIsUndef(true);
- }
- }
-
- LiveInterval &JunkLI = LIS->getInterval(JunkReg);
- if (LIS->shrinkToUses(&JunkLI)) {
- SmallVector<LiveInterval *, 8> SplitLIs;
- LIS->splitSeparateComponents(JunkLI, SplitLIs);
-
- VRM->grow();
- Register Original = VRM->getOriginal(JunkReg);
- for (LiveInterval *SplitLI : SplitLIs) {
- VRM->setIsSplitFromReg(SplitLI->reg(), Original);
- VRM->assignVirt2Phys(SplitLI->reg(), PhysReg);
+ LIS->removeAllRegUnitsForPhysReg(MO.getReg());
+ }
}
}
}
+
+ // Directly perform the rewrite, and do not leave it to VirtRegRewriter as
+ // usual. This avoids trying to manage illegal overlapping assignments in
+ // LiveRegMatrix.
+ MRI->replaceRegWith(FailedReg, PhysReg);
+ LIS->removeInterval(FailedReg);
}
void RegAllocBase::enqueue(const LiveInterval *LI) {