Skip to content

Commit 6b056f3

Browse files
vpykhtinmichaelselehov
authored andcommitted
[regalloc] Fix dangling pointers left in LiveRegMatrix.
1 parent 89f4c74 commit 6b056f3

File tree

6 files changed

+56
-5
lines changed

6 files changed

+56
-5
lines changed

llvm/include/llvm/CodeGen/LiveIntervalUnion.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ class LiveIntervalUnion {
9393
// Remove a live virtual register's segments from this union.
9494
void extract(const LiveInterval &VirtReg, const LiveRange &Range);
9595

96+
// Remove all segments referencing VirtReg. This may be used if the register
97+
// isn't used anymore.
98+
void clear_all_segments_referencing(const LiveInterval &VirtReg);
99+
96100
// Remove all inserted virtual registers.
97101
void clear() { Segments.clear(); ++Tag; }
98102

llvm/include/llvm/CodeGen/LiveRegMatrix.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ class LiveRegMatrix {
135135
/// the assignment and updates VirtRegMap accordingly.
136136
void unassign(const LiveInterval &VirtReg);
137137

138+
void unassign(Register VirtReg);
139+
138140
/// Returns true if the given \p PhysReg has any live intervals assigned.
139141
bool isPhysRegUsed(MCRegister PhysReg) const;
140142

llvm/lib/CodeGen/InlineSpiller.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
8686
const TargetInstrInfo &TII;
8787
const TargetRegisterInfo &TRI;
8888
const MachineBlockFrequencyInfo &MBFI;
89+
LiveRegMatrix &Matrix;
8990

9091
InsertPointAnalysis IPA;
9192

@@ -129,16 +130,17 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
129130

130131
public:
131132
HoistSpillHelper(const Spiller::RequiredAnalyses &Analyses,
132-
MachineFunction &mf, VirtRegMap &vrm)
133+
MachineFunction &mf, VirtRegMap &vrm, LiveRegMatrix &matrix)
133134
: MF(mf), LIS(Analyses.LIS), LSS(Analyses.LSS), MDT(Analyses.MDT),
134135
VRM(vrm), MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
135136
TRI(*mf.getSubtarget().getRegisterInfo()), MBFI(Analyses.MBFI),
136-
IPA(LIS, mf.getNumBlockIDs()) {}
137+
Matrix(matrix), IPA(LIS, mf.getNumBlockIDs()) {}
137138

138139
void addToMergeableSpills(MachineInstr &Spill, int StackSlot,
139140
Register Original);
140141
bool rmFromMergeableSpills(MachineInstr &Spill, int StackSlot);
141142
void hoistAllSpills();
143+
bool LRE_CanEraseVirtReg(Register) override;
142144
void LRE_DidCloneVirtReg(Register, Register) override;
143145
};
144146

@@ -191,7 +193,7 @@ class InlineSpiller : public Spiller {
191193
: MF(MF), LIS(Analyses.LIS), LSS(Analyses.LSS), VRM(VRM),
192194
MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
193195
TRI(*MF.getSubtarget().getRegisterInfo()), Matrix(Matrix),
194-
HSpiller(Analyses, MF, VRM), VRAI(VRAI) {}
196+
HSpiller(Analyses, MF, VRM, *Matrix), VRAI(VRAI) {}
195197

196198
void spill(LiveRangeEdit &, AllocationOrder *Order = nullptr) override;
197199
ArrayRef<Register> getSpilledRegs() override { return RegsToSpill; }
@@ -1750,6 +1752,20 @@ void HoistSpillHelper::hoistAllSpills() {
17501752
}
17511753
}
17521754

1755+
/// Called before a virtual register is erased from LiveIntervals.
1756+
/// Forcibly remove the register from LiveRegMatrix before it's deleted,
1757+
/// preventing dangling pointers.
1758+
bool HoistSpillHelper::LRE_CanEraseVirtReg(Register VirtReg) {
1759+
// If this virtual register is assigned to a physical register,
1760+
// unassign it from LiveRegMatrix before the interval is deleted.
1761+
// Use unassign_and_clear_all_refs() instead of unassign() because the
1762+
// LiveInterval may already be empty or in an inconsistent state.
1763+
if (VRM.hasPhys(VirtReg)) {
1764+
Matrix.unassign(VirtReg);
1765+
}
1766+
return true; // Allow deletion to proceed
1767+
}
1768+
17531769
/// For VirtReg clone, the \p New register should have the same physreg or
17541770
/// stackslot as the \p old register.
17551771
void HoistSpillHelper::LRE_DidCloneVirtReg(Register New, Register Old) {

llvm/lib/CodeGen/LiveIntervalUnion.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ void LiveIntervalUnion::extract(const LiveInterval &VirtReg,
7979
}
8080
}
8181

82+
void LiveIntervalUnion::clear_all_segments_referencing(
83+
const LiveInterval &VirtReg) {
84+
++Tag;
85+
86+
// Remove all segments referencing VirtReg.
87+
for (SegmentIter SegPos = Segments.begin(); SegPos.valid();) {
88+
if (SegPos.value() == &VirtReg)
89+
SegPos.erase();
90+
else
91+
++SegPos;
92+
}
93+
}
94+
8295
void
8396
LiveIntervalUnion::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const {
8497
if (empty()) {

llvm/lib/CodeGen/LiveRegMatrix.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,21 @@ void LiveRegMatrix::unassign(const LiveInterval &VirtReg) {
144144
LLVM_DEBUG(dbgs() << '\n');
145145
}
146146

147+
void LiveRegMatrix::unassign(Register VirtReg) {
148+
Register PhysReg = VRM->getPhys(VirtReg);
149+
LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg, TRI)
150+
<< " from " << printReg(PhysReg, TRI) << ':');
151+
VRM->clearVirt(VirtReg);
152+
153+
assert(LIS->hasInterval(VirtReg));
154+
const LiveInterval &LI = LIS->getInterval(VirtReg);
155+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
156+
Matrix[Unit].clear_all_segments_referencing(LI);
157+
}
158+
++NumUnassigned;
159+
LLVM_DEBUG(dbgs() << '\n');
160+
}
161+
147162
bool LiveRegMatrix::isPhysRegUsed(MCRegister PhysReg) const {
148163
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
149164
if (!Matrix[Unit].empty())

llvm/lib/Target/AMDGPU/SIPreAllocateWWMRegs.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,11 @@ void SIPreAllocateWWMRegs::rewriteRegs(MachineFunction &MF) {
153153
SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
154154

155155
for (unsigned Reg : RegsToRewrite) {
156-
LIS->removeInterval(Reg);
157-
158156
const Register PhysReg = VRM->getPhys(Reg);
159157
assert(PhysReg != 0);
158+
159+
Matrix->unassign(Reg);
160+
LIS->removeInterval(Reg);
160161

161162
MFI->reserveWWMRegister(PhysReg);
162163
}

0 commit comments

Comments
 (0)