In Machine CSE pass, the source register of a COPY machine instruction can

be propagated to all its users, and this propagation could increase the 
probability of finding common subexpressions. If the COPY has only one user,
the COPY itself can be removed.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215344 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jiangning Liu 2014-08-11 05:17:19 +00:00
parent 1505fa4376
commit 0679d2d0a4
2 changed files with 64 additions and 11 deletions

View File

@ -79,7 +79,8 @@ namespace {
SmallVector<MachineInstr*, 64> Exps;
unsigned CurrVN;
bool PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB);
bool PerformTrivialCopyPropagation(MachineInstr *MI,
MachineBasicBlock *MBB);
bool isPhysDefTriviallyDead(unsigned Reg,
MachineBasicBlock::const_iterator I,
MachineBasicBlock::const_iterator E) const;
@ -113,8 +114,12 @@ INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
INITIALIZE_PASS_END(MachineCSE, "machine-cse",
"Machine Common Subexpression Elimination", false, false)
bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
MachineBasicBlock *MBB) {
/// The source register of a COPY machine instruction can be propagated to all
/// its users, and this propagation could increase the probability of finding
/// common subexpressions. If the COPY has only one user, the COPY itself can
/// be removed.
bool MachineCSE::PerformTrivialCopyPropagation(MachineInstr *MI,
MachineBasicBlock *MBB) {
bool Changed = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
@ -123,10 +128,7 @@ bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
unsigned Reg = MO.getReg();
if (!TargetRegisterInfo::isVirtualRegister(Reg))
continue;
if (!MRI->hasOneNonDBGUse(Reg))
// Only coalesce single use copies. This ensure the copy will be
// deleted.
continue;
bool OnlyOneUse = MRI->hasOneNonDBGUse(Reg);
MachineInstr *DefMI = MRI->getVRegDef(Reg);
if (!DefMI->isCopy())
continue;
@ -154,10 +156,14 @@ bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
continue;
DEBUG(dbgs() << "Coalescing: " << *DefMI);
DEBUG(dbgs() << "*** to: " << *MI);
// Propagate SrcReg of copies to MI.
MO.setReg(SrcReg);
MRI->clearKillFlags(SrcReg);
DefMI->eraseFromParent();
++NumCoalesces;
// Coalesce single use copies.
if (OnlyOneUse) {
DefMI->eraseFromParent();
++NumCoalesces;
}
Changed = true;
}
@ -454,13 +460,15 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
bool FoundCSE = VNT.count(MI);
if (!FoundCSE) {
// Look for trivial copy coalescing opportunities.
if (PerformTrivialCoalescing(MI, MBB)) {
// Using trivial copy propagation to find more CSE opportunities.
if (PerformTrivialCopyPropagation(MI, MBB)) {
Changed = true;
// After coalescing MI itself may become a copy.
if (MI->isCopyLike())
continue;
// Try again to see if CSE is possible.
FoundCSE = VNT.count(MI);
}
}

View File

@ -0,0 +1,45 @@
; RUN: llc < %s -mtriple=aarch64-linux-gnuabi -O2 | FileCheck %s
; marked as external to prevent possible optimizations
@a = external global i32
@b = external global i32
@c = external global i32
@d = external global i32
@e = external global i32
define void @combine-sign-comparisons-by-cse(i32 *%arg) {
; CHECK: cmp
; CHECK: b.ge
; CHECK-NOT: cmp
; CHECK: b.le
entry:
%a = load i32* @a, align 4
%b = load i32* @b, align 4
%c = load i32* @c, align 4
%d = load i32* @d, align 4
%e = load i32* @e, align 4
%cmp = icmp slt i32 %a, %e
br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
land.lhs.true:
%cmp1 = icmp eq i32 %b, %c
br i1 %cmp1, label %return, label %if.end
lor.lhs.false:
%cmp2 = icmp sgt i32 %a, %e
br i1 %cmp2, label %land.lhs.true3, label %if.end
land.lhs.true3:
%cmp4 = icmp eq i32 %b, %d
br i1 %cmp4, label %return, label %if.end
if.end:
br label %return
return:
%retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
store i32 %a, i32 *%arg
ret void
}