diff options
-rw-r--r-- | lib/CodeGen/MachineCSE.cpp | 77 | ||||
-rw-r--r-- | test/CodeGen/Thumb2/thumb2-cbnz.ll | 4 | ||||
-rw-r--r-- | test/CodeGen/X86/cmp-redundant.ll | 43 |
3 files changed, 29 insertions, 95 deletions
diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index 341afd9..f97ccf6 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -33,8 +33,6 @@ STATISTIC(NumCoalesces, "Number of copies coalesced"); 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 { @@ -84,8 +82,7 @@ namespace { MachineBasicBlock::const_iterator E) const ; bool hasLivePhysRegDefUses(const MachineInstr *MI, const MachineBasicBlock *MBB, - SmallSet<unsigned,8> &PhysRefs, - SmallVector<unsigned,8> &PhysDefs) const; + SmallSet<unsigned,8> &PhysRefs) const; bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI, SmallSet<unsigned,8> &PhysRefs) const; bool isCSECandidate(MachineInstr *MI); @@ -192,8 +189,7 @@ MachineCSE::isPhysDefTriviallyDead(unsigned Reg, /// instruction does not uses a physical register. bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI, const MachineBasicBlock *MBB, - SmallSet<unsigned,8> &PhysRefs, - SmallVector<unsigned,8> &PhysDefs) const{ + SmallSet<unsigned,8> &PhysRefs) 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); @@ -210,7 +206,6 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI, 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); @@ -221,43 +216,35 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI, bool MachineCSE::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI, SmallSet<unsigned,8> &PhysRefs) const { - // Look backward from MI to find CSMI. + // 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; unsigned LookAheadLeft = LookAheadLimit; - MachineBasicBlock *CurBB = MI->getParent(); - MachineBasicBlock::const_reverse_iterator I(MI); - MachineBasicBlock::const_reverse_iterator E(CurBB->rend()); while (LookAheadLeft) { - while (LookAheadLeft && I != E) { - // Skip over dbg_value's. - while (I != E && I->isDebugValue()) - ++I; - - if (I == E) break; - - if (&*I == CSMI) - return true; + // Skip over dbg_value's. + while (I != E && I->isDebugValue()) + ++I; - 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; - } + if (I == E) + return true; - --LookAheadLeft; - ++I; + 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; } - // 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(); + + --LookAheadLeft; + ++I; } return false; @@ -408,8 +395,7 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) { // 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; - SmallVector<unsigned,8> DirectPhysRefs; - if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs, DirectPhysRefs)) { + if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs)) { FoundCSE = false; // ... Unless the CS is local and it also defines the physical register @@ -462,15 +448,6 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) { 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) - if (!MBB->isLiveIn(*PI)) - MBB->addLiveIn(*PI); - } ++NumCSEs; if (!PhysRefs.empty()) ++NumPhysCSEs; diff --git a/test/CodeGen/Thumb2/thumb2-cbnz.ll b/test/CodeGen/Thumb2/thumb2-cbnz.ll index 0ca9764..10a4985 100644 --- a/test/CodeGen/Thumb2/thumb2-cbnz.ll +++ b/test/CodeGen/Thumb2/thumb2-cbnz.ll @@ -21,8 +21,8 @@ bb7: ; preds = %bb3 bb9: ; preds = %bb7 ; CHECK: cmp r0, #0 -; CHECK-NOT: cmp -; CHECK: cbnz +; CHECK: cmp r0, #0 +; CHECK-NEXT: cbnz %0 = tail call double @floor(double %b) nounwind readnone ; <double> [#uses=0] br label %bb11 diff --git a/test/CodeGen/X86/cmp-redundant.ll b/test/CodeGen/X86/cmp-redundant.ll deleted file mode 100644 index 39d3440..0000000 --- a/test/CodeGen/X86/cmp-redundant.ll +++ /dev/null @@ -1,43 +0,0 @@ -; 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 -} - -define i32 @cmp2(i32 %a, i32 %b) nounwind readnone ssp { -entry: - %cmp = icmp sgt i32 %a, %b - br i1 %cmp, label %return, label %if.end -; CHECK: cmp2: -; 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 -} |