Skip to content

Commit c01ebe8

Browse files
committed
Handle multiple kills for a preceding definition.
1 parent caf3018 commit c01ebe8

File tree

2 files changed

+76
-18
lines changed

2 files changed

+76
-18
lines changed

llvm/lib/CodeGen/MachineLateInstrsCleanup.cpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ class MachineLateInstrsCleanup {
4848
return MI && MI->isIdenticalTo(*ArgMI);
4949
}
5050
};
51-
51+
typedef SmallDenseMap<Register, TinyPtrVector<MachineInstr *>> Reg2MIVecMap;
5252
std::vector<Reg2MIMap> RegDefs;
53-
std::vector<Reg2MIMap> RegKills;
53+
std::vector<Reg2MIVecMap> RegKills;
5454

5555
// Walk through the instructions in MBB and remove any redundant
5656
// instructions.
5757
bool processBlock(MachineBasicBlock *MBB);
5858

5959
void removeRedundantDef(MachineInstr *MI);
6060
void clearKillsForDef(Register Reg, MachineBasicBlock *MBB,
61-
BitVector &VisitedPreds);
61+
BitVector &VisitedPreds, MachineInstr *ToRemoveMI);
6262

6363
public:
6464
bool run(MachineFunction &MF);
@@ -135,33 +135,39 @@ bool MachineLateInstrsCleanup::run(MachineFunction &MF) {
135135
// definition.
136136
void MachineLateInstrsCleanup::clearKillsForDef(Register Reg,
137137
MachineBasicBlock *MBB,
138-
BitVector &VisitedPreds) {
138+
BitVector &VisitedPreds,
139+
MachineInstr *ToRemoveMI) {
139140
VisitedPreds.set(MBB->getNumber());
140141

141-
// Kill flag in MBB
142-
if (MachineInstr *KillMI = RegKills[MBB->getNumber()].lookup(Reg)) {
143-
KillMI->clearRegisterKills(Reg, TRI);
144-
return;
145-
}
142+
// Clear kill flag(s) in MBB, that have been seen after the preceding
143+
// definition. If Reg or one of its subregs was killed, it would actually
144+
// be ok to stop after removing that (and any other) kill-flag, but it
145+
// doesn't seem noticeably faster while it would be a bit more complicated.
146+
Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber()];
147+
if (MBBKills.contains(Reg))
148+
for (auto *KillMI : MBBKills[Reg])
149+
KillMI->clearRegisterKills(Reg, TRI);
146150

147-
// Def in MBB (missing kill flag)
148-
if (MachineInstr *DefMI = RegDefs[MBB->getNumber()].lookup(Reg))
149-
if (DefMI->getParent() == MBB)
150-
return;
151+
// Definition in current MBB: done.
152+
Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber()];
153+
MachineInstr *DefMI = MBBDefs[Reg];
154+
assert(DefMI->isIdenticalTo(*ToRemoveMI) && "Previous def not identical?");
155+
if (DefMI->getParent() == MBB)
156+
return;
151157

152158
// If an earlier def is not in MBB, continue in predecessors.
153159
if (!MBB->isLiveIn(Reg))
154160
MBB->addLiveIn(Reg);
155161
assert(!MBB->pred_empty() && "Predecessor def not found!");
156162
for (MachineBasicBlock *Pred : MBB->predecessors())
157163
if (!VisitedPreds.test(Pred->getNumber()))
158-
clearKillsForDef(Reg, Pred, VisitedPreds);
164+
clearKillsForDef(Reg, Pred, VisitedPreds, ToRemoveMI);
159165
}
160166

161167
void MachineLateInstrsCleanup::removeRedundantDef(MachineInstr *MI) {
162168
Register Reg = MI->getOperand(0).getReg();
163169
BitVector VisitedPreds(MI->getMF()->getNumBlockIDs());
164-
clearKillsForDef(Reg, MI->getParent(), VisitedPreds);
170+
clearKillsForDef(Reg, MI->getParent(), VisitedPreds, MI);
165171
MI->eraseFromParent();
166172
++NumRemoved;
167173
}
@@ -197,7 +203,7 @@ static bool isCandidate(const MachineInstr *MI, Register &DefedReg,
197203
bool MachineLateInstrsCleanup::processBlock(MachineBasicBlock *MBB) {
198204
bool Changed = false;
199205
Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber()];
200-
Reg2MIMap &MBBKills = RegKills[MBB->getNumber()];
206+
Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber()];
201207

202208
// Find reusable definitions in the predecessor(s).
203209
if (!MBB->pred_empty() && !MBB->isEHPad() &&
@@ -247,8 +253,8 @@ bool MachineLateInstrsCleanup::processBlock(MachineBasicBlock *MBB) {
247253
MBBDefs.erase(Reg);
248254
MBBKills.erase(Reg);
249255
} else if (MI.findRegisterUseOperandIdx(Reg, TRI, true /*isKill*/) != -1)
250-
// Keep track of register kills.
251-
MBBKills[Reg] = &MI;
256+
// Keep track of all instructions that fully or partially kills Reg.
257+
MBBKills[Reg].push_back(&MI);
252258
}
253259

254260
// Record this MI for potential later reuse.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# RUN: llc -mtriple=s390x-linux-gnu -run-pass=machine-latecleanup %s -o - -mcpu=z16 \
2+
# RUN: -verify-machineinstrs 2>&1 | FileCheck %s
3+
4+
# Kill flag of $r0q (super-reg) needs to be removed, and $r0l needs to be added as live-in.
5+
# CHECK-LABEL: name: fun0
6+
# CHECK-LABEL: bb.0:
7+
# CHECK: renamable $r0l = LHIMux -1
8+
# CHECK-NEXT: J %bb.1
9+
# CHECK-LABEL: bb.1:
10+
# CHECK-NEXT: liveins: $r0l
11+
# CHECK: renamable $r1d = LGFI 0
12+
# CHECK-NEXT: ST128 renamable $r0q, $r15d, 168, $noreg
13+
# CHECK-NEXT: ST killed renamable $r0l, $r15d, 160, $noreg
14+
# CHECK-NEXT: Return
15+
---
16+
name: fun0
17+
tracksRegLiveness: true
18+
body: |
19+
bb.0:
20+
renamable $r0l = LHIMux -1
21+
J %bb.1
22+
23+
bb.1:
24+
renamable $r1d = LGFI 0
25+
ST128 killed renamable $r0q, $r15d, 168, $noreg
26+
renamable $r0l = LHIMux -1
27+
ST killed renamable $r0l, $r15d, 160, $noreg
28+
Return
29+
...
30+
31+
# Kill flags of both $r1d and $r0q (super-reg) need to be removed.
32+
# CHECK-LABEL: name: fun1
33+
# CHECK-LABEL: bb.0:
34+
# CHECK-NEXT: renamable $r1d = LLILL 1
35+
# CHECK-NEXT: STG renamable $r1d, killed $r15d, 8, $noreg
36+
# CHECK-NEXT: renamable $r0d = LLILL 0
37+
# CHECK-NEXT: ST128 renamable $r0q, $r15d, 0, $noreg
38+
# CHECK-NEXT: STG killed renamable $r1d, killed $r15d, 8, $noreg
39+
# CHECK-NEXT: Return
40+
---
41+
name: fun1
42+
tracksRegLiveness: true
43+
body: |
44+
bb.0:
45+
renamable $r1d = LLILL 1
46+
STG killed renamable $r1d, killed $r15d, 8, $noreg
47+
renamable $r0d = LLILL 0
48+
ST128 killed renamable $r0q, $r15d, 0, $noreg
49+
renamable $r1d = LLILL 1
50+
STG killed renamable $r1d, killed $r15d, 8, $noreg
51+
Return
52+
...

0 commit comments

Comments
 (0)