Skip to content

Commit 0fe4608

Browse files
committed
Re-commit r130862 with a minor change to avoid an iterator running off the edge in some cases.
Original message: Teach MachineCSE how to do simple cross-block CSE involving physregs. This allows, for example, eliminating duplicate cmpl's on x86. Part of rdar://problem/8259436 . llvm-svn: 130877
1 parent c7e4fa7 commit 0fe4608

File tree

3 files changed

+73
-29
lines changed

3 files changed

+73
-29
lines changed

llvm/lib/CodeGen/MachineCSE.cpp

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ STATISTIC(NumCoalesces, "Number of copies coalesced");
3333
STATISTIC(NumCSEs, "Number of common subexpression eliminated");
3434
STATISTIC(NumPhysCSEs,
3535
"Number of physreg referencing common subexpr eliminated");
36+
STATISTIC(NumCrossBlockPhysCSEs,
37+
"Number of physreg common subexprs cross-block eliminated");
3638
STATISTIC(NumCommutes, "Number of copies coalesced after commuting");
3739

3840
namespace {
@@ -82,7 +84,8 @@ namespace {
8284
MachineBasicBlock::const_iterator E) const ;
8385
bool hasLivePhysRegDefUses(const MachineInstr *MI,
8486
const MachineBasicBlock *MBB,
85-
SmallSet<unsigned,8> &PhysRefs) const;
87+
SmallSet<unsigned,8> &PhysRefs,
88+
SmallVector<unsigned,8> &PhysDefs) const;
8689
bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
8790
SmallSet<unsigned,8> &PhysRefs) const;
8891
bool isCSECandidate(MachineInstr *MI);
@@ -189,7 +192,8 @@ MachineCSE::isPhysDefTriviallyDead(unsigned Reg,
189192
/// instruction does not uses a physical register.
190193
bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
191194
const MachineBasicBlock *MBB,
192-
SmallSet<unsigned,8> &PhysRefs) const {
195+
SmallSet<unsigned,8> &PhysRefs,
196+
SmallVector<unsigned,8> &PhysDefs) const{
193197
MachineBasicBlock::const_iterator I = MI; I = llvm::next(I);
194198
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
195199
const MachineOperand &MO = MI->getOperand(i);
@@ -206,6 +210,7 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
206210
if (MO.isDef() &&
207211
(MO.isDead() || isPhysDefTriviallyDead(Reg, I, MBB->end())))
208212
continue;
213+
PhysDefs.push_back(Reg);
209214
PhysRefs.insert(Reg);
210215
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias)
211216
PhysRefs.insert(*Alias);
@@ -216,35 +221,43 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
216221

217222
bool MachineCSE::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
218223
SmallSet<unsigned,8> &PhysRefs) const {
219-
// For now conservatively returns false if the common subexpression is
220-
// not in the same basic block as the given instruction.
221-
MachineBasicBlock *MBB = MI->getParent();
222-
if (CSMI->getParent() != MBB)
223-
return false;
224-
MachineBasicBlock::const_iterator I = CSMI; I = llvm::next(I);
225-
MachineBasicBlock::const_iterator E = MI;
224+
// Look backward from MI to find CSMI.
226225
unsigned LookAheadLeft = LookAheadLimit;
226+
MachineBasicBlock *CurBB = MI->getParent();
227+
MachineBasicBlock::const_reverse_iterator I(MI);
228+
MachineBasicBlock::const_reverse_iterator E(CurBB->rend());
227229
while (LookAheadLeft) {
228-
// Skip over dbg_value's.
229-
while (I != E && I->isDebugValue())
230-
++I;
230+
while (LookAheadLeft && I != E) {
231+
// Skip over dbg_value's.
232+
while (I != E && I->isDebugValue())
233+
++I;
231234

232-
if (I == E)
233-
return true;
235+
if (I == E) break;
234236

235-
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
236-
const MachineOperand &MO = I->getOperand(i);
237-
if (!MO.isReg() || !MO.isDef())
238-
continue;
239-
unsigned MOReg = MO.getReg();
240-
if (TargetRegisterInfo::isVirtualRegister(MOReg))
241-
continue;
242-
if (PhysRefs.count(MOReg))
243-
return false;
244-
}
237+
if (&*I == CSMI)
238+
return true;
245239

246-
--LookAheadLeft;
247-
++I;
240+
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
241+
const MachineOperand &MO = I->getOperand(i);
242+
if (!MO.isReg() || !MO.isDef())
243+
continue;
244+
unsigned MOReg = MO.getReg();
245+
if (TargetRegisterInfo::isVirtualRegister(MOReg))
246+
continue;
247+
if (PhysRefs.count(MOReg))
248+
return false;
249+
}
250+
251+
--LookAheadLeft;
252+
++I;
253+
}
254+
// Go back another BB; for now, only go back at most one BB.
255+
MachineBasicBlock *CSBB = CSMI->getParent();
256+
if (!CSBB->isSuccessor(CurBB) || CurBB->pred_size() != 1)
257+
return false;
258+
CurBB = CSBB;
259+
I = CSBB->rbegin();
260+
E = CSBB->rend();
248261
}
249262

250263
return false;
@@ -395,7 +408,8 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
395408
// used, then it's not safe to replace it with a common subexpression.
396409
// It's also not safe if the instruction uses physical registers.
397410
SmallSet<unsigned,8> PhysRefs;
398-
if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs)) {
411+
SmallVector<unsigned,8> DirectPhysRefs;
412+
if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs, DirectPhysRefs)) {
399413
FoundCSE = false;
400414

401415
// ... Unless the CS is local and it also defines the physical register
@@ -448,6 +462,14 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
448462
MRI->clearKillFlags(CSEPairs[i].second);
449463
}
450464
MI->eraseFromParent();
465+
if (!DirectPhysRefs.empty() && CSMI->getParent() != MBB) {
466+
assert(CSMI->getParent()->isSuccessor(MBB));
467+
++NumCrossBlockPhysCSEs;
468+
SmallVector<unsigned,8>::iterator PI = DirectPhysRefs.begin(),
469+
PE = DirectPhysRefs.end();
470+
for (; PI != PE; ++PI)
471+
MBB->addLiveIn(*PI);
472+
}
451473
++NumCSEs;
452474
if (!PhysRefs.empty())
453475
++NumPhysCSEs;

llvm/test/CodeGen/Thumb2/thumb2-cbnz.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ bb7: ; preds = %bb3
2121

2222
bb9: ; preds = %bb7
2323
; CHECK: cmp r0, #0
24-
; CHECK: cmp r0, #0
25-
; CHECK-NEXT: cbnz
24+
; CHECK-NOT: cmp
25+
; CHECK: cbnz
2626
%0 = tail call double @floor(double %b) nounwind readnone ; <double> [#uses=0]
2727
br label %bb11
2828

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; RUN: llc < %s -mtriple=x86_64-apple-darwin10 | FileCheck %s
2+
3+
define i32 @cmp(i32* %aa, i32* %bb) nounwind readnone ssp {
4+
entry:
5+
%a = load i32* %aa
6+
%b = load i32* %bb
7+
%cmp = icmp sgt i32 %a, %b
8+
br i1 %cmp, label %return, label %if.end
9+
; CHECK: cmp:
10+
; CHECK: cmpl
11+
; CHECK: jg
12+
if.end: ; preds = %entry
13+
; CHECK-NOT: cmpl
14+
; CHECK: cmov
15+
%cmp4 = icmp slt i32 %a, %b
16+
%. = select i1 %cmp4, i32 2, i32 111
17+
br label %return
18+
19+
return: ; preds = %if.end, %entry
20+
%retval.0 = phi i32 [ 1, %entry ], [ %., %if.end ]
21+
ret i32 %retval.0
22+
}

0 commit comments

Comments
 (0)