[llvm-commits] [llvm] r130877 - in /llvm/trunk: lib/CodeGen/MachineCSE.cpp test/CodeGen/Thumb2/thumb2-cbnz.ll test/CodeGen/X86/cmp-redundant.ll
Eli Friedman
eli.friedman at gmail.com
Wed May 4 15:10:37 PDT 2011
Author: efriedma
Date: Wed May 4 17:10:36 2011
New Revision: 130877
URL: http://llvm.org/viewvc/llvm-project?rev=130877&view=rev
Log:
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 .
Added:
llvm/trunk/test/CodeGen/X86/cmp-redundant.ll
Modified:
llvm/trunk/lib/CodeGen/MachineCSE.cpp
llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll
Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=130877&r1=130876&r2=130877&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Wed May 4 17:10:36 2011
@@ -33,6 +33,8 @@
STATISTIC(NumCSEs, "Number of common subexpression eliminated");
STATISTIC(NumPhysCSEs,
"Number of physreg referencing common subexpr eliminated");
+STATISTIC(NumCrossBlockPhysCSEs,
+ "Number of physreg common subexprs cross-block eliminated");
STATISTIC(NumCommutes, "Number of copies coalesced after commuting");
namespace {
@@ -82,7 +84,8 @@
MachineBasicBlock::const_iterator E) const ;
bool hasLivePhysRegDefUses(const MachineInstr *MI,
const MachineBasicBlock *MBB,
- SmallSet<unsigned,8> &PhysRefs) const;
+ SmallSet<unsigned,8> &PhysRefs,
+ SmallVector<unsigned,8> &PhysDefs) const;
bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
SmallSet<unsigned,8> &PhysRefs) const;
bool isCSECandidate(MachineInstr *MI);
@@ -189,7 +192,8 @@
/// instruction does not uses a physical register.
bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
const MachineBasicBlock *MBB,
- SmallSet<unsigned,8> &PhysRefs) const {
+ SmallSet<unsigned,8> &PhysRefs,
+ SmallVector<unsigned,8> &PhysDefs) const{
MachineBasicBlock::const_iterator I = MI; I = llvm::next(I);
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
@@ -206,6 +210,7 @@
if (MO.isDef() &&
(MO.isDead() || isPhysDefTriviallyDead(Reg, I, MBB->end())))
continue;
+ PhysDefs.push_back(Reg);
PhysRefs.insert(Reg);
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias)
PhysRefs.insert(*Alias);
@@ -216,35 +221,43 @@
bool MachineCSE::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
SmallSet<unsigned,8> &PhysRefs) const {
- // For now conservatively returns false if the common subexpression is
- // not in the same basic block as the given instruction.
- MachineBasicBlock *MBB = MI->getParent();
- if (CSMI->getParent() != MBB)
- return false;
- MachineBasicBlock::const_iterator I = CSMI; I = llvm::next(I);
- MachineBasicBlock::const_iterator E = MI;
+ // Look backward from MI to find CSMI.
unsigned LookAheadLeft = LookAheadLimit;
+ MachineBasicBlock *CurBB = MI->getParent();
+ MachineBasicBlock::const_reverse_iterator I(MI);
+ MachineBasicBlock::const_reverse_iterator E(CurBB->rend());
while (LookAheadLeft) {
- // Skip over dbg_value's.
- while (I != E && I->isDebugValue())
- ++I;
-
- if (I == E)
- return true;
+ while (LookAheadLeft && I != E) {
+ // Skip over dbg_value's.
+ while (I != E && I->isDebugValue())
+ ++I;
+
+ if (I == E) break;
+
+ if (&*I == CSMI)
+ return true;
+
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = I->getOperand(i);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+ unsigned MOReg = MO.getReg();
+ if (TargetRegisterInfo::isVirtualRegister(MOReg))
+ continue;
+ if (PhysRefs.count(MOReg))
+ return false;
+ }
- for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = I->getOperand(i);
- if (!MO.isReg() || !MO.isDef())
- continue;
- unsigned MOReg = MO.getReg();
- if (TargetRegisterInfo::isVirtualRegister(MOReg))
- continue;
- if (PhysRefs.count(MOReg))
- return false;
+ --LookAheadLeft;
+ ++I;
}
-
- --LookAheadLeft;
- ++I;
+ // Go back another BB; for now, only go back at most one BB.
+ MachineBasicBlock *CSBB = CSMI->getParent();
+ if (!CSBB->isSuccessor(CurBB) || CurBB->pred_size() != 1)
+ return false;
+ CurBB = CSBB;
+ I = CSBB->rbegin();
+ E = CSBB->rend();
}
return false;
@@ -395,7 +408,8 @@
// used, then it's not safe to replace it with a common subexpression.
// It's also not safe if the instruction uses physical registers.
SmallSet<unsigned,8> PhysRefs;
- if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs)) {
+ SmallVector<unsigned,8> DirectPhysRefs;
+ if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs, DirectPhysRefs)) {
FoundCSE = false;
// ... Unless the CS is local and it also defines the physical register
@@ -448,6 +462,14 @@
MRI->clearKillFlags(CSEPairs[i].second);
}
MI->eraseFromParent();
+ if (!DirectPhysRefs.empty() && CSMI->getParent() != MBB) {
+ assert(CSMI->getParent()->isSuccessor(MBB));
+ ++NumCrossBlockPhysCSEs;
+ SmallVector<unsigned,8>::iterator PI = DirectPhysRefs.begin(),
+ PE = DirectPhysRefs.end();
+ for (; PI != PE; ++PI)
+ MBB->addLiveIn(*PI);
+ }
++NumCSEs;
if (!PhysRefs.empty())
++NumPhysCSEs;
Modified: llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll?rev=130877&r1=130876&r2=130877&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/thumb2-cbnz.ll Wed May 4 17:10:36 2011
@@ -21,8 +21,8 @@
bb9: ; preds = %bb7
; CHECK: cmp r0, #0
-; CHECK: cmp r0, #0
-; CHECK-NEXT: cbnz
+; CHECK-NOT: cmp
+; CHECK: cbnz
%0 = tail call double @floor(double %b) nounwind readnone ; <double> [#uses=0]
br label %bb11
Added: llvm/trunk/test/CodeGen/X86/cmp-redundant.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/cmp-redundant.ll?rev=130877&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/cmp-redundant.ll (added)
+++ llvm/trunk/test/CodeGen/X86/cmp-redundant.ll Wed May 4 17:10:36 2011
@@ -0,0 +1,22 @@
+; RUN: llc < %s -mtriple=x86_64-apple-darwin10 | FileCheck %s
+
+define i32 @cmp(i32* %aa, i32* %bb) nounwind readnone ssp {
+entry:
+ %a = load i32* %aa
+ %b = load i32* %bb
+ %cmp = icmp sgt i32 %a, %b
+ br i1 %cmp, label %return, label %if.end
+; CHECK: cmp:
+; CHECK: cmpl
+; CHECK: jg
+if.end: ; preds = %entry
+; CHECK-NOT: cmpl
+; CHECK: cmov
+ %cmp4 = icmp slt i32 %a, %b
+ %. = select i1 %cmp4, i32 2, i32 111
+ br label %return
+
+return: ; preds = %if.end, %entry
+ %retval.0 = phi i32 [ 1, %entry ], [ %., %if.end ]
+ ret i32 %retval.0
+}
More information about the llvm-commits
mailing list