Teach machine cse to commute instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121903 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-12-15 22:16:21 +00:00
parent 0406356cd4
commit a63cde26ff
2 changed files with 59 additions and 2 deletions

View File

@ -24,7 +24,6 @@
#include "llvm/ADT/ScopedHashTable.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
using namespace llvm;
@ -33,6 +32,7 @@ STATISTIC(NumCoalesces, "Number of copies coalesced");
STATISTIC(NumCSEs, "Number of common subexpression eliminated");
STATISTIC(NumPhysCSEs,
"Number of physreg referencing common subexpr eliminated");
STATISTIC(NumCommutes, "Number of copies coalesced after commuting");
namespace {
class MachineCSE : public MachineFunctionPass {
@ -368,7 +368,22 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
FoundCSE = VNT.count(MI);
}
}
// FIXME: commute commutable instructions?
// Commute commutable instructions.
bool Commuted = false;
if (!FoundCSE && MI->getDesc().isCommutable()) {
MachineInstr *NewMI = TII->commuteInstruction(MI);
if (NewMI) {
Commuted = true;
FoundCSE = VNT.count(NewMI);
if (NewMI != MI)
// New instruction. It doesn't need to be kept.
NewMI->eraseFromParent();
else if (!FoundCSE)
// MI was changed but it didn't help, commute it back!
(void)TII->commuteInstruction(MI);
}
}
// If the instruction defines physical registers and the values *may* be
// used, then it's not safe to replace it with a common subexpression.
@ -430,6 +445,8 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
++NumCSEs;
if (!PhysRefs.empty())
++NumPhysCSEs;
if (Commuted)
++NumCommutes;
} else {
DEBUG(dbgs() << "*** Not profitable, avoid CSE!\n");
VNT.insert(MI, CurrVN++);

View File

@ -37,3 +37,43 @@ bb3:
declare void @bar(i32*)
declare fastcc i8* @foo(%struct.s2*) nounwind
; rdar://8773371
declare void @printf(...) nounwind
define void @commute(i32 %test_case, i32 %scale) nounwind ssp {
; CHECK: commute:
entry:
switch i32 %test_case, label %sw.bb307 [
i32 1, label %sw.bb
i32 2, label %sw.bb
i32 3, label %sw.bb
]
sw.bb: ; preds = %entry, %entry, %entry
%mul = mul nsw i32 %test_case, 3
%mul20 = mul nsw i32 %mul, %scale
br i1 undef, label %if.end34, label %sw.bb307
if.end34: ; preds = %sw.bb
; CHECK: %if.end34
; CHECK: imull
; CHECK: leal
; CHECK-NOT: imull
tail call void (...)* @printf(i32 %test_case, i32 %mul20) nounwind
%tmp = mul i32 %scale, %test_case
%tmp752 = mul i32 %tmp, 3
%tmp753 = zext i32 %tmp752 to i64
br label %bb.nph743.us
for.body53.us: ; preds = %bb.nph743.us, %for.body53.us
%exitcond = icmp eq i64 undef, %tmp753
br i1 %exitcond, label %bb.nph743.us, label %for.body53.us
bb.nph743.us: ; preds = %for.body53.us, %if.end34
br label %for.body53.us
sw.bb307: ; preds = %sw.bb, %entry
ret void
}